Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for RabbitMQ By James Joyner IV · · 9 min read

RabbitMQ Error Guide: 'basic.nack' Publisher Confirm Negative Acknowledgement

Fix RabbitMQ publisher nacks: diagnose basic.nack received under publisher confirms from failed persistence, leader failover, or resource alarms.

  • #rabbitmq
  • #troubleshooting
  • #errors
  • #publishing

Exact Error Message

Under publisher confirms, the broker returns a negative acknowledgement for one or more published messages:

# Java client
handleNack(deliveryTag=48213, multiple=false): broker nacked published message

# pika
Basic.Nack(delivery_tag=48213, multiple=False, requeue=False)  # to the publisher

# broker log around the same time
Stopping message store for directory '/var/lib/rabbitmq/mnesia/.../msg_stores'
operation queue.declare caused internal error; failed to persist message to queue
 'orders' on node rabbit@mq-02

This is a publisher nack (basic.nack from broker to publisher in confirm mode). It is not a consumer nack/reject, which flows the other direction (consumer to broker) to refuse a delivery.

What the Error Means

When you enable publisher confirms with confirm.select, the broker promises to send basic.ack once it has taken responsibility for a message (routed and, for persistent messages, persisted/replicated). If the broker cannot take responsibility, it instead sends basic.nack. A nack means: “I received your publish, but I could not safely handle it — treat it as not delivered.”

This is the publisher-side safety net. A nack is rare and signals real broker-side trouble: the message store failed to persist, a quorum queue could not replicate to a majority, an internal error occurred, or a resource condition prevented acceptance. A correct publisher treats a nacked message exactly like a failed publish and retries (idempotently) or routes it to a fallback.

It is important not to confuse the four publisher-side outcomes. An ack means the broker took responsibility. A nack means the broker received the publish but could not safely handle it. A return (basic.return, with mandatory) means the message was unroutable — a routing problem, not a persistence one. And a silent loss is what happens when you use none of these mechanisms. Only ack plus nack handling, ideally combined with mandatory and basic.return, gives a publisher a complete and accurate picture of what actually happened to each message.

Common Causes

  • A queue could not persist the message. Disk failure, a corrupted or full message store, or an I/O error on the data directory prevents the broker from durably storing a delivery_mode=2 message.
  • Quorum queue leader failover mid-publish. The leader changed before the message was committed to a majority, so the in-flight publish is nacked rather than silently lost.
  • Quorum queue cannot reach a majority. Too few members are online to commit the write, so the broker nacks instead of acking.
  • A resource alarm interacts with confirms. Under memory/disk pressure the broker may nack rather than accept, especially for streams/quorum queues that must persist.
  • An internal broker error on the queue process. A crash or exception in the queue’s Erlang process causes outstanding confirms to be nacked.
  • x-overflow=reject-publish on a full queue. A bounded queue at x-max-length with reject-publish overflow nacks new publishes once full.

How to Reproduce the Error

Bound a quorum queue with reject-publish overflow and fill it past the limit with confirms on:

queue.declare(queue='orders', durable=true,
  arguments={'x-queue-type':'quorum','x-max-length':1000,'x-overflow':'reject-publish'})
confirm.select()
loop:
  basic.publish(routing_key='orders', delivery_mode=2, body=...)
  # after the 1000th message:
  #   handleNack(deliveryTag=1001) -> broker rejects further publishes

You can also reproduce a persistence nack by stopping a majority of a quorum queue’s members and publishing durable messages to it — the broker cannot commit and nacks.

Diagnostic Commands

# Outstanding/unconfirmed publishes per channel (rising = confirms not arriving as acks)
rabbitmqctl list_channels pid number messages_unconfirmed | head -20

# Quorum queue health: members, online count, and leader
rabbitmqctl list_queues name type leader members online --sort=name | grep -i quorum

# Detailed quorum queue status (per queue)
rabbitmq-diagnostics quorum_status orders

# Resource alarms that can force nacks
rabbitmqctl status | grep -iA4 'Alarms'

# Queue overflow / max-length policies that reject-publish
rabbitmqctl list_policies | grep -iE 'overflow|max-length'
rabbitmqctl list_queues name arguments | grep -i reject-publish

# Persistence / message store errors in the log
journalctl -u rabbitmq-server --since "1 hour ago" | grep -iE 'persist|msg_store|nack|reject-publish'

Cross-reference the time of the nack with the broker log: a persistence error, a quorum membership drop (online < majority), or an alarm at the same moment pinpoints the cause.

Step-by-Step Resolution

  1. Confirm it is a publisher nack, not a consumer nack. A handleNack/Basic.Nack delivered to the publisher in confirm mode is broker-side rejection. A consumer nack is your own code refusing a delivery.

  2. Check for resource alarms. Run rabbitmqctl status | grep -iA4 Alarms. Under an alarm, relieve the resource (drain/purge a backed-up queue, free disk) so the broker can accept and persist again.

  3. Check quorum queue membership. Run rabbitmq-diagnostics quorum_status <queue> and list_queues ... online. If fewer than a majority of members are online, restore the down nodes so writes can commit. A failover mid-publish causes transient nacks that should clear once a leader is stable.

  4. Investigate persistence errors. Search the log for msg_store/persist errors. A failing disk or corrupted store must be fixed at the infrastructure level; check df -h and disk health for the data directory.

  5. Check overflow policy. If the queue uses x-overflow=reject-publish at x-max-length, nacks are expected when full — drain consumers or raise the limit if the rejection is unwanted.

  6. Handle nacks in the publisher. Treat a nacked message as a failed send: retry with backoff (idempotently) or route to a dead-letter/fallback. Never assume a nacked message was delivered.

  7. Verify. After fixing the underlying cause, re-publish and confirm messages_unconfirmed drains via basic.ack and no further nacks appear.

Prevention and Best Practices

  • Always implement nack handling alongside ack handling; a confirm callback that ignores nacks loses data.
  • Make publishes idempotent (dedup keys) so retrying a nacked message is safe.
  • Use quorum queues with enough members online to keep a majority available during single-node maintenance.
  • Keep the data volume healthy and monitored; persistence nacks usually trace to disk problems.
  • Set sensible x-max-length + overflow policies and alert before queues hit the limit.
  • Monitor messages_unconfirmed and nack rate; any sustained nack rate is a broker-health incident.
  • basic.publish failed (404/NO_ROUTE): routing-time failures, distinct from a post-acceptance nack.
  • resource alarm: the broker-wide condition that can force nacks (or block publishers entirely).
  • quorum cannot reach majority: the replication failure that produces persistence nacks on quorum queues.
  • quorum Ra command timeout: a related quorum-queue failure where commits time out rather than nack immediately.

Frequently Asked Questions

What is the difference between a publisher nack and a consumer nack? A publisher nack (basic.nack broker to publisher, in confirm mode) means the broker could not take responsibility for a published message. A consumer nack (basic.nack consumer to broker) is your consumer refusing a delivery so it is requeued or dead-lettered.

Does a nack mean the message is lost? It means the broker did not take responsibility for it. The publisher must retry or route it elsewhere; treat it as a failed send.

Why would a quorum queue nack my publish? If it cannot replicate to a majority of members (nodes down) or a leader failover occurs mid-publish, the broker nacks rather than risk an uncommitted write.

Are nacks common? No. Under a healthy broker they are rare. A sustained nack rate signals disk problems, quorum membership loss, or a resource alarm.

Do I need confirms to see nacks? Yes. Nacks only exist in publisher-confirm mode (confirm.select). Without confirms, the same conditions cause silent loss instead.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.