A RabbitMQ publisher sends a message to an exchange, which routes it to bound queues. Publisher confirms tell the client that the broker handled a publish under the queue's confirmation rules; they are not proof that an application consumer completed work. An AMQP 0-9-1 publish that matches no queue may be discarded when the mandatory flag is false and no alternate exchange handles it. With mandatory publishing, an unroutable message is returned to the publisher, which must register and act on the return. Reliable publishing therefore needs both a routing outcome and a confirm outcome, correlated with the original business event ID.
RabbitMQ publishing: distinguish broker confirmation from queue routing
Operational decision
An invoice service emits event inv-7284 to an exchange using routing key settlement.ready. A staging binding is accidentally renamed. The producer enables mandatory publishing, handles returned messages, and waits for confirms. It records the event as delivered only when the message was not returned and the broker confirmed it. If the channel closes before the confirm, the outcome is ambiguous: the service retries from its outbox with the same business ID, and the consumer deduplicates that ID. A confirm cannot replace the outbox transaction if database commit and publish are separate actions. The operator tests a removed binding and a lost connection before accepting the topology.
Exchange: settlement-events
Routing key: settlement.ready
Business event: inv-7284
mandatory: true; returned-message handler: required
confirmed + not returned: broker accepted route
connection lost before confirm: ambiguous, retry same business IDCost and verification
Confirm tracking consumes memory per unacknowledged publish and adds round-trip or batched waiting time. Large outstanding windows make reconnect recovery harder because more events have uncertain status. A returned message is a topology defect, not an ordinary transient retry target; alert on it with the exchange and routing key. Confirm rates and return rates should be observed together. Test the actual queue binding, not just a producer callback. Downstream processing still requires manual consumer acknowledgment and an idempotent effect ledger when duplicates would cause harm.
Common Mistakes
- Do not interpret a publisher confirm as a consumer acknowledgment.
- Do not discard mandatory returns while recording the publish as delivered.
- Do not create a new business ID for an ambiguous retry.
Connected lessons
- DevOps: delivery, infrastructure, and reliable operations
- Transactional outbox: commit business state and event intent together
- Queue consumers: acknowledgement, idempotency, and backlog
- Event schema evolution: release consumers before new event shapes
- RabbitMQ publishing: distinguish broker confirmation from queue routing
- RabbitMQ quorum queues: plan node maintenance around majority availability
