Dead Letter Queue Alert Monitor
Scheduled flow checks Azure Queue dead letter messages and alerts the team in Teams with details of failed operations.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
FlowLibs - Dead Letter Queue Alert Monitor is a scheduled cloud flow that continuously inspects an Azure Storage Queue used as a dead-letter queue (DLQ) for failed/poison messages produced by other automations. When the DLQ contains one or more messages, the flow notifies the configured Microsoft Teams channel and emails an HTML summary table to the IT/Ops distribution list so the owning team can investigate and remediate the underlying processing flow.
The flow runs hourly out of the box, peeks up to 32 messages with a short visibility timeout, and surfaces the message metadata (Message ID, Insertion Time, Expiration Time, Dequeue Count, Preview) without removing the messages permanently — operators decide how to handle each message after they are alerted.
Use Case
In production, automations frequently route unrecoverable failures to a "poison" or DLQ queue (Azure Queue convention: <queueName>-poison or dlq-<queueName>). Without an alert, those messages sit silently and downstream business processes appear "stuck" with no obvious cause. This flow gives Ops a 1-hour SLA on detecting any failed message that lands in the configured DLQ — Teams alert + emailed table → triage in the run history of the upstream flow → remediate → drain or republish the message.
Flow Architecture
Recurrence Every Hour
RecurrenceFires once per hour (configurable to any frequency).
Initialize Storage Account Name
InitializeVariable (string)Holds `flowlibs_AzureQueueStorageAccountName`.
Initialize Dead Letter Queue Name
InitializeVariable (string)Holds `flowlibs_DeadLetterQueueName`.
Initialize Teams Group Id
InitializeVariable (string)Holds `flowlibs_TeamsGroupId`.
Initialize Teams Channel Id
InitializeVariable (string)Holds `flowlibs_TeamsChannelId`.
Initialize Alert Email Recipient
InitializeVariable (string)Holds `flowlibs_ITTeamEmail`.
Get Dead Letter Messages
OpenApiConnection (shared_azurequeues / GetMessages_V2)Reads up to 32 messages from the DLQ with a 30-second visibility timeout (messages auto-reappear so the next run still sees them).
Initialize Dead Letter Count
InitializeVariable (integer)Sets value to `length(coalesce(body('Get_Dead_Letter_Messages')?['QueueMessagesList']?['QueueMessage'], createArray()))`.
Check If Dead Letter Messages Exist
If conditionEvaluates `greater(@variables('varDeadLetterCount'), 0)`. When the DLQ is empty, the If branch is skipped and the run completes silently — no Teams or email noise.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_AzureQueueStorageAccountName | String | flowlibsdemo | Azure Storage account hosting the DLQ. |
| flowlibs_DeadLetterQueueName | String | dlq-orders | Queue name within the storage account that holds dead-letter messages. |
| flowlibs_TeamsGroupId | String | <configure> | Microsoft Teams group (team) ID for the Teams alert. Replace with the real Teams group GUID. |
| flowlibs_TeamsChannelId | String | <configure> | Channel inside the team to post to. Replace with the real Teams channel ID. |
| flowlibs_ITTeamEmail | String | alerts@yourcompany.com | Email distribution that receives the summary table. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Azure Queues | shared_azurequeues | GetMessages_V2 (Reads up to 32 messages from the DLQ) |
| Microsoft Teams | shared_teams | PostMessageToConversation (Posts the alert card to the configured channel) |
| Office 365 Outlook | shared_office365 | SendEmailV2 (Sends the HTML summary email to the IT distribution) |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Change polling cadence
- Edit the Recurrence Every Hour trigger — set frequency to Minute and interval to e.g. 15 for every 15 min.
- Cover multiple DLQs
- Either clone the solution per queue, or wrap the Get Dead Letter Messages + downstream actions in an Apply-to-each over a JSON array of queue names. The recommended pattern is one solution per DLQ so each can have an independent SLA, runbook owner, and audit trail.
- Auto-archive instead of just alerting
- Insert a SharePoint Create item (or Dataverse CreateRecord) action between Steps 8.3 and 8.4 to log every dead-lettered message to a list/table for trend analysis. Then add a Delete message action (shared_azurequeues / DeleteMessage_V2) inside an Apply-to-each to drain the queue after archiving — only do this if archival is the responsible owner of the message.
- Suppress noise during business hours
- Wrap the If branch with another condition that compares formatDateTime(utcNow(), 'HH') to a window — only post Teams alerts during 08–18 local time, but keep the email summary 24/7.
- Severity tiers
- Branch on varDeadLetterCount (e.g. > 10 posts to a higher-priority Teams channel and emails the on-call paging address; otherwise low-volume notification).
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Initialize Dead Letter Count value
`coalesce(..., createArray())` defends against the connector returning `null` when the queue is empty.
EXPR.02Select Message Summaries For HTML `from`
Same defensive pattern — falls back to an empty array when the queue is empty.
EXPR.03Select `Preview` projection
Caps preview at 200 chars and survives empty/missing message text.
EXPR.04Compose Email HTML Table body
The Select projects each row as a single string; `join(..., '')` concatenates them inline.
EXPR.05Send Email Subject
Includes the count and queue name for easy triage in inbox.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.