We've got our queues configured to send dead letter messages (nack'ed messages specifically) to a dead letter exchange that routes them by their original topic to individual dead letter queues. This all works great and when messages are nack'ed they're sent to the correct dead letter queue.
The trouble comes in when we shovel those messages back from the dlq to the normal queue, where they get nack'ed again. For some reason, this second time through they just disappear instead of being sent back to the dead letter exchange.
I assume there's some sort of "circular message routing" detection going on, but can't find anything like that. Inspecting the messages the second time through gives all the expected headers so I'm not sure what such a thing could even be based on. Any suggestions of where to look next or if rabbit has such a thing would be greatly appreciated!
If it's necessary, our consumers are written in python using the pika library for communication.
Assuming that you have the following queues/exchanges:
Exchanges
global_exchange- your main exchangeDLX- another exchange specifically for dead-lettersQueues
queue- your main queue withinglobal_exchange. Containsarguments=x-dead-letter-exchange: 'DLX'queue.dlq- your dead-letter queue withinglobal_exchangeBindings
test_messagerouting_key bound toqueueandqueue.dlqFinally, I assume that you are using the shovel plugin on the
queue.dlqmanagement page like this, to move messages fromqueue.dlqintoqueue:Here is how the routing works when you send a message with
test_messageas therouting_keyto theglobal_exchange:queuefrom the binding ontest_messagex-dead-letter-exchangeargument sends it toDLXwithrouting_key= test_messagequeue.dlqbinding, that queue receives the messageWhen you use that particular management panel to shovel messages back into
queue, it uses the default exchange. This changes the routing key. So the 2nd receipt of the message has a routing key that is equal to the name of the queue you are shoveling into.Since you do not have an
x-dead-letter-routing-keyconfigured, the message is dead-lettered to the current routing key:So on the result of the shovel, this is how it is routed:
queuewithrouting_key = queueDLXwithrouting_key = queuequeueinDLX, message droppedThere 2 potential workarounds:
queue.dlqtorouting_key = queuex-dead-letter-routing-keyonqueueto always send to the same routing key on dead-letter no matter what message was originally sent to it and ensure there is a binding to it withinDLX