Tarmac

DLQ & Redrive

Inspect dead-letter queues and surgically redrive messages back to their source queue.

How Tarmac Finds DLQs

Tarmac reads each queue's redrive policy and cross-references the queue list: any queue named as another queue's dead-letter target is grouped under the Dead-letter section in the rail (and matchable with the DLQ type filter). When you select a DLQ, Tarmac calls SQS's ListDeadLetterSourceQueues to resolve which queue(s) feed it — so redrive works even if the source queue isn't in your current list view.

The Redrive Action

Redrive is a staged action (see Staged Actions) that, on publish, sends the message to its source queue and then deletes it from the DLQ. The first resolved source queue is used as the target; if no source queue exists, redrive staging is disabled.

Two properties of this implementation are worth understanding:

  • It's per-message send-then-delete, not a native queue-level move. That's exactly what makes it surgical: you pick the individual messages that deserve another chance, optionally after inspecting every one of them, and leave the rest.
  • Send and delete are two API calls. In the rare case where the send succeeds but the delete fails, the message exists in both queues and the action reports "delete failed after send." Your consumer should treat this as ordinary at-least-once redelivery — see SQS Essentials.

Fix the consumer before you redrive

A redriven message that hits the same bug lands right back in the DLQ — with a higher receive count. The productive order is: inspect the DLQ, identify the failure class (facets on error fields make this fast), deploy the fix, then redrive. Redrive is the last step of an incident, not the first.

Selective Redrive vs. Bulk Redrive

Tarmac's redrive is built for selective work: tens to hundreds of messages that you've filtered, inspected, and chosen. Each message costs one send and one delete, published sequentially, and each needs a live receipt handle from this session's fetch.

For bulk redrives — "move all 50,000 messages back" with no inspection — the AWS console's native DLQ redrive (StartMessageMoveTask) is the better tool: it runs server-side, needs no receipt handles, and doesn't depend on your laptop staying open. Use Tarmac to decide whether and what to redrive; use native redrive when the answer is "everything."

A Typical DLQ Session

  1. Select the DLQ and fetch with a long visibility timeout (e.g. 900s) — you'll be inspecting for a while, and delete/redrive needs handles that are still live at publish time.
  2. Open facets on the error fields to bucket the failures.
  3. For each bucket: inspect a few representatives. Fixable by a code change? Fix and redrive. Malformed beyond saving? Stage deletes. Wrong payload but salvageable? Edit & Resend to the source queue, then stage a delete for the original.
  4. Review the Staged tab and Publish before the visibility window closes.
  5. Watch the source queue (Live Tail) to confirm redriven messages are being consumed — and not boomeranging back into the DLQ.

Mind maxReceiveCount when browsing source queues

Messages move to a DLQ when their receive count exceeds the source queue's max-receive setting — and every receive counts, including Tarmac's. On a queue with a low threshold (1–3), browsing with repeated fetches can itself push messages into the DLQ. Check the threshold in Topology ("Max receives" chip), fetch once, and work from the cache.

On this page