0
0
RabbitmqHow-ToBeginner · 4 min read

How to Requeue Message in RabbitMQ: Simple Steps

To requeue a message in RabbitMQ, use the basic.reject or basic.nack method with the requeue=true flag. This tells RabbitMQ to put the message back into the queue for redelivery instead of discarding or dead-lettering it.
📐

Syntax

RabbitMQ provides two main methods to reject a message and optionally requeue it:

  • basic.reject(deliveryTag, requeue): Rejects a single message. requeue is a boolean to decide if the message goes back to the queue.
  • basic.nack(deliveryTag, multiple, requeue): Can reject multiple messages. multiple is a boolean to reject multiple messages up to deliveryTag. requeue decides if messages are requeued.

Parameters:

  • deliveryTag: The unique ID of the message delivery.
  • requeue: true to put the message back in the queue, false to discard or dead-letter.
  • multiple: (Only for basic.nack) true to reject multiple messages, false for one.
java
channel.basicReject(deliveryTag, true);

// or

channel.basicNack(deliveryTag, false, true);
💻

Example

This example shows how to consume a message and requeue it if processing fails. It uses basic.nack with requeue=true to put the message back into the queue.

java
import com.rabbitmq.client.*;

public class RequeueExample {
    private final static String QUEUE_NAME = "task_queue";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {

            channel.queueDeclare(QUEUE_NAME, true, false, false, null);
            System.out.println("Waiting for messages...");

            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                String message = new String(delivery.getBody(), "UTF-8");
                System.out.println("Received: " + message);

                try {
                    // Simulate processing
                    if (message.contains("fail")) {
                        throw new RuntimeException("Processing failed");
                    }
                    System.out.println("Processed successfully");
                    channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
                } catch (Exception e) {
                    System.out.println("Processing failed, requeuing message");
                    channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, true);
                }
            };

            channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> { });

            // Keep program running
            Thread.sleep(10000);
        }
    }
}
Output
Waiting for messages... Received: task1 Processed successfully Received: fail_task Processing failed, requeuing message Received: fail_task Processing failed, requeuing message ...
⚠️

Common Pitfalls

  • Forgetting to set requeue=true causes the message to be discarded or dead-lettered instead of requeued.
  • Using basic.reject for multiple messages is not possible; use basic.nack instead.
  • Not acknowledging or rejecting messages can cause them to remain unacknowledged and block the queue.
  • Requeuing messages too many times without fixing the cause can lead to infinite loops.
java
/* Wrong: message discarded instead of requeued */
channel.basicReject(deliveryTag, false);

/* Right: message requeued for redelivery */
channel.basicReject(deliveryTag, true);
📊

Quick Reference

MethodPurposeRequeue ParameterNotes
basic.rejectReject single messagetrue to requeueCannot reject multiple messages
basic.nackReject one or more messagestrue to requeueSupports multiple message rejection with 'multiple' flag
basic.ackAcknowledge message processedN/AUse to confirm successful processing

Key Takeaways

Use basic.reject or basic.nack with requeue=true to put messages back into the queue.
basic.nack supports rejecting multiple messages; basic.reject only one.
Always acknowledge or reject messages to avoid blocking the queue.
Requeueing messages repeatedly without fixing issues can cause infinite loops.
Set requeue=false to discard or dead-letter messages instead of requeuing.