RabbitMQ Error: 'reject-publish' queue overflow returning basic.nack to publishers
Fix RabbitMQ x-overflow reject-publish nacks: diagnose max-length/max-length-bytes limits, confirm publisher nacks, tune queue overflow, and stop dropped messages.
- #rabbitmq
- #messaging
- #troubleshooting
- #errors
Stuck on this RabbitMQ error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Exact Error Message
With publisher confirms enabled, a queue configured with x-overflow: reject-publish returns a basic.nack once it is full:
2026-07-17 09:14:22.108 [warning] <0.1841.0> Queue 'events' in vhost '/' is full
(max-length 50000), rejecting publish with basic.nack (overflow: reject-publish)
Client side (Java) the publisher sees the nack surfaced by the confirm listener:
com.rabbitmq.client.ConfirmListener.handleNack: delivery tag 41922, multiple=false
Broker rejected publish: queue 'events' at capacity (x-overflow=reject-publish)
If confirms are not enabled the message is simply discarded with no error, and you only notice via a growing gap between published and delivered counts.
What It Means
Every RabbitMQ queue can carry a length limit via x-max-length (message count) or x-max-length-bytes (total bytes). When that limit is reached, the x-overflow argument decides what happens to new messages. The default is drop-head, which silently discards the oldest ready message. Setting reject-publish instead tells the broker to refuse the new message.
Under reject-publish, a refused publish is reported to the publisher with basic.nack — but only if that channel is in publisher-confirm mode. A nack here means “the broker looked at your message and declined it because this queue is full,” not that the broker crashed or lost data. The related mode reject-publish-dlx additionally routes the rejected message to the queue’s configured dead-letter exchange.
Common Causes
- The queue hit
x-max-lengthorx-max-length-bytesbecause consumers are slower than publishers. - A policy set
overflowtoreject-publishintentionally, and a burst of traffic filled the queue. - Consumers are down, disconnected, or stuck on unacked messages, so
messages_readynever drains. - The limit was set too low for normal peak load.
- A fan-out binds many queues and one slow queue starts nacking while others keep up.
Diagnostic Commands
Show current depth, the configured limit, and the overflow behavior for the queue:
rabbitmqctl list_queues name messages messages_ready messages_unacknowledged arguments --vhost /
Inspect the effective policy that set the overflow argument:
rabbitmqctl list_policies --vhost /
rabbitmq-diagnostics list_policies --vhost /
Check whether consumers are actually attached and draining:
rabbitmqctl list_queues name consumers messages_ready messages_unacknowledged --vhost /
Watch the broker log for reject/overflow warnings:
journalctl -u rabbitmq-server --since "10 min ago" | grep -iE 'overflow|reject|is full'
A queue with messages_ready pinned at the limit and consumers = 0 (or high messages_unacknowledged) is the classic signature: publishers keep arriving, nothing is being acknowledged, so every new publish is nacked.
Step-by-Step Resolution
-
Confirm this is a capacity nack, not a routing failure. A
basic.nackunder confirms with the queue at itsx-max-lengthis overflow rejection. Abasic.returnis unroutable-message handling — a different problem. -
Find the limit and current depth:
rabbitmqctl list_queues name messages messages_ready arguments --vhost / | grep -i events -
Fix the real bottleneck first — the consumers. If
consumers = 0ormessages_unacknowledgedis high, restart or scale consumers and raiseprefetchsomessages_readydrains below the limit. -
If the limit is genuinely too low, raise it via policy (policies are the recommended way to manage limits, not per-queue
x-arguments):rabbitmqctl set_policy events-limit "^events$" \ '{"max-length":200000,"overflow":"reject-publish"}' \ --apply-to queues --vhost / -
Preserve rejected messages instead of losing them by switching to
reject-publish-dlxand configuring a dead-letter exchange:rabbitmqctl set_policy events-limit "^events$" \ '{"max-length":200000,"overflow":"reject-publish-dlx","dead-letter-exchange":"events.dlx"}' \ --apply-to queues --vhost / -
Make publishers handle the nack. Ensure publisher confirms are enabled and treat a nack as backpressure: slow down, retry with jitter, or shed load. Silently ignoring nacks turns a visible reject into invisible data loss.
-
Verify the queue drains and publishes are accepted again:
rabbitmqctl list_queues name messages_ready consumers --vhost /
Prevention
- Choose the overflow mode deliberately:
drop-headfor lossy telemetry,reject-publish/reject-publish-dlxfor work that must not be silently dropped. - Always enable publisher confirms when using
reject-publish; without them, rejected messages vanish with no signal. - Alert on
messages_readyapproachingx-max-lengthbefore it saturates. - Size limits to real peak load with headroom, and scale consumers to keep queues short.
- Route rejects to a DLX so overflow is recoverable rather than lost. See the prompt library for AI prompts that generate policy and consumer-scaling runbooks.
Related Errors
- NO_ROUTE (312) basic.return — an unroutable message, not a full queue.
- resource alarm / connection.blocked — a broker-wide memory or disk alarm blocks publishers instead of nacking one queue.
- publisher nack under mirroring/quorum — a nack because a quorum could not be reached, not because of length overflow.
- drop-head silent loss — the default overflow mode discards without any nack.
Frequently Asked Questions
Why do I get a nack instead of an error on publish? With reject-publish and publisher confirms on, a full queue is reported asynchronously via basic.nack, not as a synchronous exception on the publish call.
Where do rejected messages go? With reject-publish they are discarded; with reject-publish-dlx they are routed to the queue’s dead-letter exchange.
Does reject-publish work without publisher confirms? No — without confirms the broker still refuses the message, but the publisher receives no signal, so it looks like silent loss.
Is drop-head or reject-publish better? Use drop-head when the newest data matters most and old data is disposable; use reject-publish when you need backpressure and must not silently drop new work.
How do I change the overflow mode safely? Update the policy that matches the queue; policy changes apply without recreating the queue, unlike x-arguments set at declaration. For more, see the RabbitMQ guides.
Fixed it? Get 500 RabbitMQ & DevOps AI prompts — free
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.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
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.