How to requeue messages in RabbitMQ
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Requeuing in RabbitMQ means telling the broker that a delivered message was not processed successfully and should be made available again. The important detail is that requeueing is a delivery decision, not a separate queue operation, so the consumer must acknowledge or reject the delivery correctly.
Core Sections
Use manual acknowledgements
If auto_ack is enabled, RabbitMQ considers the message handled as soon as it is delivered to the consumer. In that mode, there is nothing left to requeue because the broker already dropped responsibility for the delivery.
Use manual acknowledgements instead.
When consuming, set auto_ack=False so your code can decide whether to ack, nack, or reject the message.
Requeue with basic_nack
The most common pattern is to negatively acknowledge the message and ask RabbitMQ to requeue it.
With requeue=True, the message goes back to the queue instead of being discarded. Another consumer, or the same consumer later, may receive it again.
Know the difference between ack, nack, and reject
RabbitMQ offers several outcomes for a delivered message:
- '
basic_ackmeans processing succeeded' - '
basic_nack(..., requeue=True)means processing failed and the message should return to the queue' - '
basic_nack(..., requeue=False)means processing failed and the message should not return to the same queue' - '
basic_rejectis similar to a negative acknowledgement for a single message'
If you have only one message to reject, basic_reject is fine. If you need broader control, basic_nack is usually more flexible.
Avoid infinite redelivery loops
Immediate requeue can become dangerous when the failure is not transient. If every consumer keeps requeueing the same poison message, the queue churns endlessly and useful work slows down.
A safer retry design uses a dead-letter exchange or a dedicated retry queue with delay semantics. The message leaves the main queue, waits, and returns later.
In that design, unrecoverable processing does not hammer the main queue continuously.
Track retry attempts in headers
If you requeue blindly, consumers cannot distinguish a first attempt from a tenth attempt. One common approach is to republish the message with a retry counter in headers and route it through a retry queue.
That gives your code a clear rule such as “retry three times, then dead-letter permanently.”
Decide when requeueing is the right tool
Requeueing is best for short-lived failures such as a temporary database lock, a downstream service timeout, or a deployment restart window. It is not the right default for bad input, schema mismatches, or messages that can never succeed. Those cases should usually be dead-lettered, logged, and handled separately.
Common Pitfalls
- Using
auto_ack=True, which removes the broker’s ability to redeliver the message after a failure. - Requeueing every exception automatically, even when the message is invalid and will fail forever.
- Creating a tight requeue loop with no delay, which wastes consumer capacity and floods logs.
- Failing to track retry count, which makes poison messages hard to identify and control.
- Confusing broker requeueing with republishing a message, even though they have different semantics and metadata behavior.
Summary
- Requeueing is controlled by how the consumer acknowledges or rejects a delivery.
- Use manual acknowledgements and
basic_nack(..., requeue=True)when a retry is appropriate. - Distinguish transient failures from permanent failures before deciding to requeue.
- Use retry queues or dead-letter exchanges to avoid hot redelivery loops.
- Track retry attempts explicitly so poison messages do not circulate forever.
Related reading
- How to reset offsets to arbitrary value in Kafka Consumer Group?
- How to reset user for rabbitmq management
- How to resolve a zookeeper authentication failure when using Kafka with Kerberos
- How to resolve Kafka error Connection to node 0 could not be established?
- How to restart a failed pod in kubernetes deployment
- How to restart apache2 without terminating docker container?
- How to resolve IndexError too many indices for array
- How to restart RabbitMQ service

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.