Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

For an AMQP 0.9.1 message, read the x-death array: each entry’s queue names the queue the message was dead-lettered from for that event, and reason explains why. The newest event appears first. RabbitMQ groups repeat events by queue and reason, so an entry’s count is not a total across the message’s entire route.

How to identify the queue and cause

  1. Find the protocol first. This field-by-field guide applies to AMQP 0.9.1, where the history is in the x-death header. AMQP 1.0 uses the x-opt-deaths message annotation instead.
  2. Read the newest entry. The array is ordered by recency, newest first. Its queue value is where that particular dead-lettering event occurred; its reason is why.
  3. Check the entry’s count. RabbitMQ compresses history by the pair {queue, reason}. The count is how many times that same pair occurred, not how many times the message was dead-lettered overall.
  4. Use first/last metadata for route endpoints. x-first-death-queue identifies the queue for the first dead-lettering event; x-last-death-queue identifies the queue for the latest. These answer a different question from the queue field in a selected historical entry.

RabbitMQ documents the header format and ordering in its Dead Letter Exchanges documentation.

What the x-death fields mean

Field Meaning
queue The queue the message was dead-lettered from for this event.
reason The cause label, such as rejected or expired.
count Occurrences for this queue-and-reason pair.
time The first time this queue-and-reason pair was recorded.
exchange The exchange to which the message had been published before the first event for this pair.
routing-keys The routing keys before the first event for this pair.
original-expiration Optional original AMQP 0.9.1 expiration property. RabbitMQ removes message expiration during dead-lettering so the routed message does not expire again.

RabbitMQ also sets x-first-death-reason and x-first-death-exchange for the first event; these first-death values are not modified later. The corresponding x-last-death-queue, x-last-death-reason, and x-last-death-exchange values are updated as later dead-lettering events occur.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What each reason tells you

Reason Operational meaning
rejected A consumer negatively acknowledged or rejected the message without requeueing it. This is the reason most directly linked to a consumer’s explicit decision.
expired The message’s time-to-live elapsed. RabbitMQ’s processing details differ by queue type: on quorum queues, an expired message is dead-lettered when it reaches the head of the queue.
maxlen A configured maximum queue length caused the message to be dropped or dead-lettered, depending on configuration.
delivery_limit A quorum queue returned the message more times than its configured delivery limit.

These are RabbitMQ’s documented reason labels. See the RabbitMQ 3.13 dead-letter documentation and its time-to-live and expiration documentation for the relevant behavior.

How dead-lettering configuration affects the diagnosis

A dead-letter exchange (DLX) must be configured for dead-letter routing. Without one, a consumer-rejected message may be dropped instead of routed to another queue. Also distinguish message expiration from queue expiration: a message can be dead-lettered when its TTL elapses, but when an entire queue expires, its messages are not dead-lettered. RabbitMQ documents these distinctions in its version 3.13 DLX documentation.

AMQP 1.0 uses a different field set

Do not look for an AMQP 0.9.1 x-death array in an AMQP 1.0 message. RabbitMQ uses the x-opt-deaths message annotation for that protocol. Its entries use fields such as first-time and last-time, and may include ttl. Client libraries may display field types and timestamp values differently. RabbitMQ’s AMQP 1.0 documentation describes the protocol-specific representation.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

RabbitMQ 4.x caveat for republished messages

RabbitMQ 4.x continues to set or update broker-managed x-death when the broker dead-letters a message. However, RabbitMQ 4.x no longer interprets an AMQP 0.9.1 x-death header supplied by a client when that client republishes a message. If an application republishes messages and needs its own retry counter, keep that counter in a separate application-managed header rather than expecting the broker to increment a client-provided x-death. This behavior is stated in the RabbitMQ 4.0.1 release notes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A practical check when a retry flow looks wrong

  • Confirm whether the message uses AMQP 0.9.1 or AMQP 1.0 before choosing the header or annotation.
  • Inspect the newest entry’s queue and reason to locate the latest dead-lettering event and its cause.
  • Compare multiple entries by queue, reason, and recency; treat each count as specific to one queue/reason pair.
  • Check the first/last death headers when you need the route’s starting or latest dead-lettering queue.
  • Verify the queue’s DLX, TTL, maximum length, or quorum delivery-limit configuration that corresponds to the reported reason.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.