Warren
Error

PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange': adding a dead-letter exchange to an existing RabbitMQ queue

2026-10-19 · 3 min read · Viktor Baumann

You add a dead-letter exchange to the queue declaration in your code, deploy, and the service no longer starts. The channel is closed with:

PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange' for queue 'orders' in vhost 'orders':
received the value 'orders.dlx' of type 'longstr' but current is none

That is the exact message RabbitMQ 4.3.6 returns. Here is what it means and how to get the dead-letter exchange onto the queue without losing a message.

What the error means

Declaring a queue that already exists is fine as long as the declaration matches: same durability, same arguments. Queue arguments (x- keys in the declare call) are fixed when the queue is created. Your code now declares orders with x-dead-letter-exchange, the queue in the broker was created without it, so RabbitMQ refuses and closes the channel. Nothing changed in the broker; the queue and its messages are untouched.

A passive declare (it only checks that the queue exists) does not compare arguments, which is why a consumer that declares passively keeps working while the publisher that declares fully fails.

The fix: a policy instead of an argument

Policies can add a dead-letter exchange to an existing queue at runtime. Set one for the queue:

rabbitmqctl set_policy -p orders orders-dlx '^orders$' \
  '{"dead-letter-exchange":"orders.dlx"}' --apply-to queues

Then remove x-dead-letter-exchange from the declaration in your code again. What we measured on 4.3.6:

Make sure orders.dlx exists and has a queue bound to it before the first message dies. A dead-letter exchange that does not exist is accepted without complaint, and every dead letter is then dropped without an error or a log line (measured: the queue declared with a missing dead-letter exchange, a rejected message gone, the channel still open).

The other ways out

Policies have one advantage beyond this error: they live in the broker, so the dead-letter setup of every queue can be changed later without a deploy, and with one pattern for many queues.