How to Configure Dead Letter Exchange in RabbitMQ: Step-by-Step Guide
To configure a
dead letter exchange (DLX) in RabbitMQ, declare an exchange and a queue to act as the dead letter destination, then set the x-dead-letter-exchange argument on the original queue to point to that exchange. Messages rejected or expired in the original queue will be routed to the DLX automatically.Syntax
To configure a dead letter exchange, you need to declare:
- Dead Letter Exchange: An exchange where dead letters are sent.
- Dead Letter Queue: A queue bound to the DLX to receive dead letters.
- Original Queue: The queue where you set the
x-dead-letter-exchangeargument to the DLX name.
The key argument is x-dead-letter-exchange set on the original queue.
python
channel.exchange_declare(exchange='my.dlx', exchange_type='direct') channel.queue_declare(queue='my.dlq') channel.queue_bind(queue='my.dlq', exchange='my.dlx', routing_key='dlx_key') args = {'x-dead-letter-exchange': 'my.dlx', 'x-dead-letter-routing-key': 'dlx_key'} channel.queue_declare(queue='my.queue', arguments=args)
Example
This example shows how to create a dead letter exchange and queue, then configure an original queue to use the DLX. Messages rejected or expired from my.queue will be routed to my.dlq.
python
import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # Declare dead letter exchange and queue channel.exchange_declare(exchange='my.dlx', exchange_type='direct') channel.queue_declare(queue='my.dlq') channel.queue_bind(queue='my.dlq', exchange='my.dlx', routing_key='dlx_key') # Declare original queue with DLX arguments args = {'x-dead-letter-exchange': 'my.dlx', 'x-dead-letter-routing-key': 'dlx_key'} channel.queue_declare(queue='my.queue', arguments=args) # Publish a message channel.basic_publish(exchange='', routing_key='my.queue', body='Test message') # Reject the message to send it to DLX method_frame, header_frame, body = channel.basic_get('my.queue') if method_frame: channel.basic_reject(delivery_tag=method_frame.delivery_tag, requeue=False) # Consume from dead letter queue method_frame, header_frame, body = channel.basic_get('my.dlq') if method_frame: print('Dead letter received:', body.decode()) channel.basic_ack(method_frame.delivery_tag) connection.close()
Output
Dead letter received: Test message
Common Pitfalls
- Not setting
x-dead-letter-exchangeon the original queue will prevent dead lettering. - Forgetting to bind the dead letter queue to the DLX means messages have nowhere to go.
- Using the wrong routing key can cause messages to be lost if no queue matches.
- Not rejecting or expiring messages properly will not trigger dead lettering.
python
## Wrong: No DLX argument channel.queue_declare(queue='my.queue') ## Right: Set DLX argument args = {'x-dead-letter-exchange': 'my.dlx'} channel.queue_declare(queue='my.queue', arguments=args)
Quick Reference
| Parameter | Description |
|---|---|
| x-dead-letter-exchange | Name of the exchange where dead letters are sent |
| x-dead-letter-routing-key | Optional routing key for dead letters |
| Dead Letter Exchange | Exchange that receives dead letters |
| Dead Letter Queue | Queue bound to the DLX to receive dead letters |
| Message rejection | Trigger for sending messages to DLX (reject or expire) |
Key Takeaways
Set the x-dead-letter-exchange argument on the original queue to enable dead lettering.
Bind a queue to the dead letter exchange to receive dead letters.
Use message rejection or TTL expiration to trigger dead lettering.
Ensure routing keys match between DLX and dead letter queue bindings.
Without proper DLX setup, undeliverable messages will be lost or discarded.