Share via

LogicAppWorkflowRuntime multiple WorkflowRunCompleted records for same RunId

Davie Lau 6 Reputation points
2026-05-29T23:24:34.1633333+00:00

Hi,

I'm running the following KQL query in log analytics:

LogicAppWorkflowRuntime
| where TimeGenerated > ago(24h)
| where OperationName == "WorkflowRunCompleted"
| order by RunId

I'm seeing duplicate records for workflows that are Failed.
User's image

These are all the same RunId with the same StartTime but the TimeGenerated and EndTime are all different times from Today. Also, the StartTime is from 3 months ago but the TimeGenerated is today. There are dozens of these records. Why does this happen? Thanks for your answers.

Azure Logic Apps
Azure Logic Apps

An Azure service that automates the access and use of data across clouds without writing code.

0 comments No comments

1 answer

Sort by: Most helpful
  1. Rakesh Mishra 9,425 Reputation points Microsoft External Staff Moderator
    2026-05-30T00:33:15.86+00:00

    Hi Davie,

    Thank you for reaching out to Microsoft Q&A.

    What you are seeing is not expected behavior for normal workflow runs. While Logic Apps (Standard) relies on the underlying Azure Durable Task framework—which uses event sourcing to replay state—a workflow that has already reached a terminal state (like Failed) should not be continuously replayed months later.

    As per official Microsoft documentation:

    "The Standard logic app and workflow is powered by the redesigned single-tenant Azure Logic Apps runtime. This runtime uses the Azure Functions extensibility model and is hosted as an extension on the Azure Functions runtime."

    Because of this architecture, Logic Apps Standard relies heavily on Azure Storage Queues (Control Queues) to dispatch and track workflow execution steps. The behavior you are observing is caused by a stuck orchestration state or a poison message in your Logic App's storage account.

    Here is what is happening under the hood:

    1. For this specific failed run from 3 months ago, the control queue message responsible for finalizing its state failed to be successfully checkpointed or deleted from the queue (possibly due to a transient storage timeout, locking issue, or memory spike at the time).
    2. Because the message was never deleted, it becomes visible again in the queue after its visibility timeout expires.
    3. The runtime picks up the message, replays the workflow to its failed state, emits the WorkflowRunCompleted telemetry to Log Analytics (which generates today's TimeGenerated and EndTime), but then repeatedly fails to finalize the storage transaction.

    This creates an infinite loop where the same old RunId keeps emitting new completion logs on a daily or hourly basis. To resolve this, you need to clear the stuck message from your storage account.

    Resolution Steps:

    Step 1: Identify the underlying Storage Account

    1. Navigate to your Standard Logic App in the Azure Portal.
    2. Under Settings, select Environment variables (or Configuration depending on portal view).
    3. Look for the application setting named AzureWebJobsStorage. Note the storage account name provided in this connection string.

    Step 2: Inspect and clear the Control Queues (Option A)

    1. Navigate to the identified Azure Storage Account in the Azure Portal.
    2. Go to Storage browser > Queues.
    3. Look for queues prefixed with your app's hub name (e.g., logicapps-control-00, logicapps-control-01, etc.).
    4. Check the Message count. If you see messages lingering in these queues that correspond to the timeframe of your ghost runs, these are the stuck messages causing your loops.
    5. To stop the loop, you can select the queue and use the Clear queue action. (Warning: Clearing the queue will drop pending execution steps for any currently active workflows in that specific partition. Only do this during a maintenance window or when there are no active running workflows).

    Step 3: Purge Instance History (Option B - Targeted Fix) If you want a more targeted fix without clearing entire queues, you can purge the stuck instance data using the Storage Tables to forcibly sever the loop:

    1. In the Storage browser, go to Tables.
    2. Locate the instances and history tables (typically named logicappsInstances and logicappsHistory or similar hub prefixes).
    3. Query the logicappsInstances table for the PartitionKey that exactly matches your stuck RunId.
    4. Delete the entities associated with that RunId. This completely removes its historical state, forcing the runtime to drop the poison message upon its next attempted replay since it will no longer find the orchestration history to rehydrate.

    Please follow above steps and let me know in comments if it works or any other issue.

    Note: This response is drafted with the help of AI systems.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.