RabbitMQ Error Guide: 'NOT_FOUND' No Queue or Exchange (404)
Fix RabbitMQ NOT_FOUND channel errors: diagnose missing queues and exchanges, wrong vhost, auto-deleted queues, typos, and declaration order race conditions.
- #rabbitmq
- #troubleshooting
- #errors
- #topology
Overview
A NOT_FOUND error (404) means a client referenced a queue or exchange that does not exist in the vhost it is connected to. It happens when you bind, publish to, consume from, or passively declare a resource that was never created, was deleted, or auto-deleted out from under you. RabbitMQ raises a channel-level exception and closes the channel; the connection survives but that channel is dead.
You will see it in the client as a channel exception:
Channel error on connection <0.1402.0> (10.0.5.31:51702 -> 10.0.4.21:5672, vhost: '/', user: 'app'):
operation queue.bind caused a channel exception not_found:
no queue 'orders.process' in vhost '/'
Or for an exchange:
NOT_FOUND - no exchange 'events.topic' in vhost '/'
The key detail is always the vhost: a queue that exists in /billing does not exist in /, and the error reports the exact name and vhost so you can confirm the mismatch.
Symptoms
- Channel closes with
NOT_FOUND - no queue '<name>'orno exchange '<name>'. - The resource clearly “should” exist but is missing in the reported vhost.
- Consumers that were running fine die when a queue is auto-deleted.
rabbitmqctl list_queues -p / name | grep orders
orders
orders.dead
If orders.process is referenced but only orders and orders.dead exist, the name (or vhost) is wrong.
Common Root Causes
1. The queue or exchange was never declared
The client assumes a resource exists but nothing created it.
rabbitmqctl list_exchanges -p / name type | grep events
events topic
A publisher targeting events.topic when the exchange is actually named events gets no exchange 'events.topic'. The resource was simply never declared under that name.
2. Wrong vhost
The resource exists, but in a different vhost than the client connected to.
for v in / billing orders; do
echo "== $v =="; rabbitmqctl list_queues -p "$v" name 2>/dev/null | grep invoices
done
== / ==
== billing ==
invoices
== orders ==
invoices lives in billing, but the client connected to / — hence no queue 'invoices' in vhost '/'. Fix the connection’s vhost.
3. Passive declare against a missing resource
A client using passive=true asserts existence without creating; if absent, it 404s.
rabbitmqadmin list queues vhost name | grep temp-results
(no rows)
A passive queue.declare for temp-results returns NOT_FOUND because passive mode never creates — it only checks. The producer is expected to have declared it first.
4. The queue was auto-deleted or expired
An auto-delete queue vanishes when its last consumer disconnects; an x-expires queue vanishes after being unused.
rabbitmqctl list_queues name auto_delete arguments | grep rpc-reply
(empty)
A previously listed rpc-reply queue declared with auto_delete=true is gone after the consumer dropped — subsequent binds/publishes to it 404.
5. Typo or environment-specific name
A name templated from config (env prefix, region suffix) doesn’t match what was created.
rabbitmqctl list_queues name | grep -i notif
prod.notifications
The client built notifications (missing the prod. prefix) and gets no queue 'notifications'. The created name carries an environment prefix the client omitted.
6. Declaration order / race between services
A consumer starts and binds before the producer service has declared the exchange/queue.
rabbitmqctl list_exchanges name | grep payments
(empty during the race window)
If the consumer’s queue.bind to payments runs before the producer declares payments, it 404s. The resource appears moments later, but the binding already failed.
Diagnostic Workflow
Step 1: Read the exact name and vhost from the error
The message gives both: no queue 'X' in vhost 'Y'. Note them verbatim — the fix is almost always reconciling one of these two against reality.
Step 2: Check whether the resource exists anywhere
rabbitmqctl list_vhosts | while read v; do
rabbitmqctl list_queues -p "$v" name 2>/dev/null | grep -H "<NAME>" && echo " ^ in $v"
done
rabbitmqctl list_exchanges -p / name | grep "<NAME>"
If it exists in a different vhost, you have a vhost mismatch. If nowhere, it was never created or was deleted.
Step 3: Confirm the client’s connection vhost
rabbitmqctl list_connections name user vhost | grep <CLIENT_IP>
Compare the connection’s vhost to where the resource actually lives. A mismatch here is the most common cause.
Step 4: Check for auto-delete / expiry that removed it
rabbitmqctl list_queues name auto_delete arguments | grep <NAME>
If the queue was auto_delete or had x-expires, it was removed legitimately when idle/unconsumed. The client must redeclare it rather than assume persistence.
Step 5: Fix the name/vhost or declare the resource
# create the missing resource in the right vhost:
rabbitmqadmin -V <VHOST> declare queue name=<NAME> durable=true
rabbitmqadmin -V <VHOST> declare exchange name=<NAME> type=topic durable=true
Or correct the client’s vhost/name so it references the existing resource.
Example Root Cause Analysis
A newly deployed consumer for the payments service crashes on startup with:
NOT_FOUND - no exchange 'payments.events' in vhost '/'
The producer team insists the exchange exists. Searching across vhosts:
for v in $(rabbitmqctl list_vhosts -q name 2>/dev/null); do
rabbitmqctl list_exchanges -p "$v" name 2>/dev/null | grep -q '^payments.events$' && echo "found in $v"
done
found in payments
The exchange exists — but in the payments vhost, not /. Confirming the consumer’s connection:
rabbitmqctl list_connections name user vhost | grep 10.0.5.40
10.0.5.40:51810 payments-consumer /
The consumer connected to the default / vhost because its connection URL omitted the vhost path, while the producer publishes into the payments vhost. The fix is the client connection string:
amqps://payments-consumer:****@mq-01:5671/payments
(Note the /payments vhost suffix.) After redeploying with the correct vhost, the consumer binds to payments.events successfully. The 404 was a vhost mismatch the error message had already spelled out.
Prevention Best Practices
- Declare topology (exchanges, queues, bindings) from a single source — definitions JSON or an init job — so consumers never depend on declaration order or a race with the producer.
- Always include the vhost explicitly in connection strings and config; an omitted vhost silently defaults to
/and produces phantom NOT_FOUND errors. - Avoid
passive=truedeclarations unless you guarantee the resource is provisioned first; otherwise have the client declare (idempotently) what it needs. - Be deliberate with
auto_deleteandx-expiresqueues — document that they are ephemeral so clients redeclare rather than assume persistence. - Centralize resource naming (env prefixes, region suffixes) in shared config so a templated name can’t drift from what was created.
- When a NOT_FOUND page fires, the free incident assistant can cross-check the named resource against the vhost in the error to spot a mismatch. More patterns in the RabbitMQ guides.
Quick Command Reference
# Does the resource exist, and in which vhost?
rabbitmqctl list_queues -p <VHOST> name | grep <NAME>
rabbitmqctl list_exchanges -p <VHOST> name | grep <NAME>
# Sweep all vhosts for the name
for v in $(rabbitmqctl list_vhosts -q name); do
rabbitmqctl list_queues -p "$v" name 2>/dev/null | grep -q "^<NAME>$" && echo "in $v"
done
# What vhost is the client actually on?
rabbitmqctl list_connections name user vhost | grep <CLIENT_IP>
# Was it auto-delete/expiring?
rabbitmqctl list_queues name auto_delete arguments | grep <NAME>
# Create the missing resource
rabbitmqadmin -V <VHOST> declare queue name=<NAME> durable=true
rabbitmqadmin -V <VHOST> declare exchange name=<NAME> type=topic durable=true
Conclusion
NOT_FOUND (404) means the named queue or exchange does not exist in the client’s vhost. The usual root causes:
- The resource was never declared under that name.
- It exists, but in a different vhost than the client connected to.
- A passive declare hit a resource that was never provisioned.
- An
auto_delete/x-expiresqueue was removed when it went idle. - A typo or missing environment prefix in the templated name.
- A declaration-order race between producer and consumer.
The error names both the resource and the vhost — reconcile those two against what actually exists, and the fix is almost always a corrected vhost, name, or a missing declaration.
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.