# Dead Letter Channel

**In short:** A Dead Letter Channel is a side queue for messages a messaging system cannot deliver or process. Failed messages wait there to be inspected, fixed and resubmitted instead of being lost.

## Explanation

A messaging system sometimes gets a message it cannot deliver. The Dead Letter Channel pattern answers what to do with it. Related patterns are the Invalid Message Channel and Message Expiration.

The idea is simple. Move the failed message to a separate queue, often called a dead-letter queue (DLQ). Teams can then look at it and find out why processing failed.

**Why messages end up there**

- No receiver can take the message, or the receiver cannot process it.
- The message is malformed. Applications can also dead-letter unacceptable messages on purpose, for example those with broken payloads.
- Delivery attempts ran out. Azure Service Bus dead-letters a message after a delivery limit, 10 by default. This is the "poison message" case: a message that keeps failing.
- In Amazon SQS, a redrive policy sets `maxReceiveCount`, the number of receives allowed before the move. It should be high enough to allow retries.
- The message expired. With dead-lettering on, Service Bus moves expired messages (time to live, or TTL, ran out) to the DLQ with the reason `TTLExpiredException`.
- RabbitMQ republishes messages to a dead letter exchange on four events. These include per-message expiry, queue length overflow, rejection and the delivery limit. The `x-death` record shows which one happened.

**What happens next**

People inspect the messages. Once the cause is fixed, they resubmit the messages for reprocessing. Service Bus supports this individually or in batches, for example with Service Bus Explorer. When an application dead-letters a message itself, it should record the exception type and stack trace. Large stack traces may hit size quotas.

**Operating it**

Service Bus never cleans its DLQ automatically. Messages stay until someone explicitly handles them. An unattended DLQ therefore just grows.

In SQS, retention in a DLQ counts from the original enqueue time for standard queues. Set the DLQ retention longer than the source queue's, or messages may be deleted early.

## Example

An order service reads "place order" messages from a queue. One message has a broken payload, and the service rejects it each time. After the allowed number of attempts, the broker moves it to the dead-letter queue. The other orders keep flowing. A developer opens the dead-lettered message, reads the recorded error, fixes the cause, and resubmits the message.

## Trade-offs

- **Ordering:** SQS warns that using a DLQ with a FIFO queue can break the exact order of messages or operations.
- **Message loss:** RabbitMQ dead-lettering by default has no publisher confirms. Messages can be lost if the target queue is unavailable. Quorum queues offer at-least-once dead-lettering.
- **Neglect:** Service Bus does no automatic cleanup, so a DLQ nobody watches only accumulates messages.
- **Retry settings:** A retry limit that is too low sends recoverable messages to the DLQ too early.

Failed or expired messages move to a dead-letter queue, then are inspected and resubmitted.

```mermaid
flowchart LR
  P[Sender] --> Q[Source queue]
  Q --> C[Consumer]
  Q -- expired --> D[Dead-letter queue]
  C -- retries exhausted --> D
  D --> I[Inspect and fix]
  I -- resubmit --> Q
```

## Checks

- The document states how many delivery attempts are allowed before a message moves to the dead-letter queue, and that the limit leaves room for retries.
- Someone is named to watch and clear the dead-letter queue, since it is not cleaned automatically.
- The DLQ retention period is longer than the source queue's retention period.
- The document explains how dead-lettered messages are inspected and resubmitted after a fix.
- The effect of a DLQ on message ordering is assessed where FIFO queues are used.

## Related

- [Invalid Message Channel](https://arc.fuet.ch/concepts/integration/invalid-message-channel.md)
- [Message Channel](https://arc.fuet.ch/concepts/integration/message-channel.md)
- [Retry](https://arc.fuet.ch/concepts/tactics/retry.md)
- [Messaging](https://arc.fuet.ch/concepts/integration/messaging.md)
- [Timeout-based Delivery](https://arc.fuet.ch/concepts/integration/timeout-based-delivery.md)
- [Idempotent Receiver](https://arc.fuet.ch/concepts/integration/idempotent-receiver.md)
- [Point-to-Point Channel](https://arc.fuet.ch/concepts/integration/point-to-point-channel.md)
- [Exception Handling Tactic](https://arc.fuet.ch/concepts/tactics/exception-handling.md)

## Sources

- [Dead Letter Channel - Enterprise Integration Patterns](https://www.enterpriseintegrationpatterns.com/patterns/messaging/DeadLetterChannel.html) — enterpriseintegrationpatterns.com, accessed 2026-11-09
- [Using dead-letter queues in Amazon SQS - Amazon Simple Queue Service](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html) — docs.aws.amazon.com, accessed 2026-11-09
- [Service Bus Dead-Letter Queues - Azure Service Bus | Microsoft Learn](https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dead-letter-queues) — learn.microsoft.com, accessed 2026-11-09
- [Dead Letter Exchanges | RabbitMQ](https://www.rabbitmq.com/docs/dlx) — rabbitmq.com, accessed 2026-11-09
