Course outline

RabbitMQ / Basic: protocol resources, routing and ownership / Lesson 4

Consumer acknowledgments and redelivery

Place acknowledgment after the required effect and recover safely when delivery or result is uncertain.

About 4 min readContent reviewed
On this page

Lesson goals

  • Explain manual acknowledgment, rejection and requeue decisions.
  • Keep channel-scoped delivery tags separate from business identity.

Acknowledgment transfers responsibility

With manual acknowledgments, RabbitMQ keeps a delivery outstanding until the consumer acknowledges it under the channel protocol. Acknowledging before the required business effect completes risks losing that work after a crash. Completing the effect and crashing before acknowledgment permits redelivery, which requires duplicate-safe handling. Automatic acknowledgment instead treats delivery as accepted under its mode and can lose work if the process fails afterward. Choose the mode from the actual loss and replay contract. A callback starting or placing work in an unbounded in-memory executor is not necessarily the business completion point.

Acknowledge on the delivery’s channel

Delivery tags are scoped to the channel that supplied them. Acknowledging a tag on another channel or acknowledging an already completed tag can trigger an unknown-delivery-tag protocol error and close the channel. Do not cache tags as durable identifiers across reconnects. The multiple flag can acknowledge a range of outstanding deliveries, so it must not accidentally cover unfinished concurrent work. Keep consumer API calls under the client's documented threading rules. A worker thread should report completion through an approved handoff rather than calling channel methods from an arbitrary context that the library does not support.

Requeue is a policy decision

A negative acknowledgment or rejection can request requeue or removal according to supported method semantics. Requeue does not repair malformed input and can create a rapid failure loop. Without requeue, dead-lettering may occur if configured; otherwise the message can be discarded. Define permanent invalid input, temporary dependency failure and terminal exhaustion separately. Preserve source operation identity and useful sanitized failure context. The redelivered flag is evidence that a delivery may be repeated, not a complete deduplication database and not a universal attempt counter. First delivery can still duplicate a business operation published twice.

Read one non-runnable acknowledgment operation

The Java fragment acknowledges one completed delivery with multiple=false. It assumes a valid channel and tag from that channel; it is not a complete client program and is never executed. A real implementation must ensure the destination effect is complete and duplicate-safe before reaching this line. If processing is delegated to an external system, define whether its acknowledgment means durable completion or only accepted work. Closing the channel immediately afterward can still leave acknowledgment uncertainty, so design for redelivery rather than assuming the last local method call makes a message impossible to receive again.

java Illustrative single-delivery acknowledgment fragment
channel.basicAck(deliveryTag, false);

channel and deliveryTag must belong to the same active delivery context; the fragment is not executed.

Protect unfinished work in a local schedule

The offline example has deliveries one and two outstanding but only one completed. It removes one and leaves two pending, illustrating per-delivery acknowledgment accounting. It does not emulate protocol frames, channel failure or broker storage. A real batch-ack policy needs a proof that every covered delivery has completed, especially when workers finish out of order. Tests should place a crash after the destination effect and before the acknowledgment. This course runs no consumer and sends no ack or nack; its assertions verify the supplied sets while keeping runtime and external-effect guarantees outside the claim.

python Offline outstanding-delivery accounting
outstanding = {1, 2}
completed = {1}
outstanding -= completed
assert outstanding == {2}
print(sorted(outstanding))
Expected output
[2]

Only the supplied completed delivery is removed; this is not a broker acknowledgment test.

Common errors and fixes

PRECONDITION_FAILED - unknown delivery tag

Why it happens
The tag was acknowledged twice, on the wrong channel or outside its valid context.
How to fix it
Correct channel ownership and acknowledgment accounting before recovering the channel.
Prevent it next time
Keep one explicit completion path per delivery.

A crash loses work that was already acknowledged.

Why it happens
Acknowledgment preceded the required durable effect.
How to fix it
Move acknowledgment to the supported business completion boundary.
Prevent it next time
Test failure immediately before and after the effect.

A malformed message loops rapidly through requeue.

Why it happens
Permanent invalid input was treated as transient.
How to fix it
Use a bounded terminal or dead-letter policy with review ownership.
Prevent it next time
Classify failure before selecting requeue.

Check your understanding

1. Does redelivered=false prove the business operation never happened before?

Show worked solution

No. The publisher can have sent the same occurrence as two separate messages, and external effects can exist independently of one delivery flag. Use stable business identity and destination-supported duplicate handling. Treat redelivery metadata as useful diagnostic context rather than the authoritative uniqueness rule.

2. Why is acknowledging through tag2 unsafe when tag1 is still being processed concurrently?

Show worked solution

A multiple acknowledgment can cover earlier outstanding deliveries as well. If tag1 is included before its work finishes, a crash can leave it skipped despite an incomplete effect. Use per-delivery acknowledgments or a reviewed completed-range policy and preserve the channel context under the client’s concurrency rules.

Key takeaways

  • Acknowledge completed responsibility, and tolerate redelivery around crashes.
  • Delivery tags are channel state, not durable business keys.

Official references