RabbitMQ Error Guide: 'RESOURCE_LOCKED - cannot obtain exclusive access' Locked Queue
Fix RabbitMQ RESOURCE_LOCKED errors: exclusive queue owned by another connection, reconnect races, and 'cannot obtain exclusive access to locked queue' fixes.
- #rabbitmq
- #troubleshooting
- #errors
- #queues
Exact Error Message
A RESOURCE_LOCKED error appears when a client tries to access an exclusive queue that is already owned by a different connection. RabbitMQ closes the channel with a 405 error:
Channel error on connection <0.2841.0> (10.0.6.12:53120 -> 10.0.4.21:5672, vhost: '/', user: 'worker'):
operation queue.declare caused a channel exception resource_locked:
cannot obtain exclusive access to locked queue 'rpc.reply-abc123' in vhost '/'.
It could be originally declared on another connection or the exclusive property value does not match that of the original declaration.
You may also see it phrased on basic.consume or queue.bind as exclusive queue in use or simply cannot obtain exclusive access.
What the Error Means
An exclusive queue is bound to the lifetime and identity of the connection that declared it. Only that one connection may declare, consume from, bind, or delete it, and the broker auto-deletes the queue the moment the owning connection drops. When any other connection — or even a new connection from the same process after a reconnect — touches that queue by name, RabbitMQ refuses with RESOURCE_LOCKED because the original owner still holds the lock.
This is not a corruption or capacity problem. The queue is healthy and working for its owner. The error signals that two connections disagree about who owns an exclusive queue, almost always because of a naming collision or a reconnect race.
Common Causes
1. Reconnect race after a dropped connection
The classic trigger: a client loses its TCP connection, the broker has not yet detected the drop, and the client reconnects and immediately redeclares the same exclusive queue. The old connection’s lock is still in place for a few seconds, so the redeclaration is rejected.
2. A fixed exclusive queue name shared across processes
Exclusive queues are meant to have server-generated or per-connection-unique names. Hard-coding a name like rpc.replies and starting two workers means the second worker collides with the first.
3. Two connections from the same application
A process that opens a separate publisher connection and consumer connection, then declares the same exclusive reply queue on both, locks itself out on the second connection.
4. Treating an exclusive queue as durable/shared
Exclusive queues never survive a connection drop. Code that expects to reattach to a previously declared exclusive queue from a brand-new connection will always hit RESOURCE_LOCKED (or NOT_FOUND if the broker already cleaned it up).
5. exclusive property mismatch on redeclare
Declaring an existing exclusive queue with exclusive=false (or vice versa) from another connection trips the same lock check.
How to Reproduce the Error
Open two connections and have both declare the same exclusive queue:
# Terminal 1 - hold an exclusive queue open
rabbitmqadmin declare queue name=demo.excl exclusive=true
# (keep this connection alive)
queue declared
# Terminal 2 - a different connection tries the same name
rabbitmqadmin declare queue name=demo.excl exclusive=true
*** Error: 405 RESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'demo.excl' in vhost '/'
The second connection cannot obtain the lock the first connection holds.
Diagnostic Commands
Use these read-only commands to identify the owning connection and confirm the queue is exclusive.
# List exclusive queues with their owner pid and state
rabbitmqctl list_queues name exclusive owner_pid state messages
# Show every connection so you can map the owner_pid to a client IP/user
rabbitmqctl list_connections pid name peer_host user connected_at state
# Inspect channels to see which connection is doing queue operations
rabbitmqctl list_channels pid connection number consumer_count
# Confirm exclusive flag and any name collision for one queue
rabbitmqctl list_queues name exclusive auto_delete owner_pid | grep rpc.reply
# Check broker logs for the resource_locked line and the offending peer
journalctl -u rabbitmq-server --since "10 min ago" | grep -i resource_locked
The owner_pid from list_queues matches a pid in list_connections, telling you exactly which client holds the lock.
Step-by-Step Resolution
Step 1: Confirm the queue is exclusive and find its owner
rabbitmqctl list_queues name exclusive owner_pid | grep <QUEUE>
rabbitmqctl list_connections pid peer_host user | grep <OWNER_PID>
If exclusive is true, the queue legitimately belongs to one connection. Identify whether that connection is a live, healthy client or a stale one the broker has not yet reaped.
Step 2: Let the old connection’s lock expire
If a reconnect race is the cause, the simplest fix is to wait for the broker to detect the dead connection. Tighten detection so the lock releases faster by enabling AMQP heartbeats (e.g. a 10-30 second heartbeat) and TCP keepalives on the client. With a short heartbeat the stale owner is dropped in tens of seconds rather than minutes, freeing the name.
Step 3: Stop hard-coding exclusive queue names
Let the broker generate the name. Declare with an empty name and exclusive=true; RabbitMQ returns a unique amq.gen-... name per connection so two processes can never collide. Use that returned name for your bindings and consumer.
Step 4: Use one connection per exclusive queue
Declare, bind, and consume the exclusive queue all on the same connection. Do not declare it on a publisher connection and consume on a separate one.
Step 5: Add reconnect backoff and redeclaration
On reconnect, redeclare the exclusive queue (it was auto-deleted with the old connection) using a fresh generated name, and add a short backoff so you are not racing the broker’s cleanup of the prior connection.
Step 6: Verify the lock is gone
rabbitmqctl list_queues name exclusive owner_pid | grep <QUEUE>
If the row is absent, the old connection was reaped and the queue auto-deleted; your client can declare cleanly.
Prevention and Best Practices
- Always let the server generate exclusive queue names — never hard-code them across processes.
- Keep declare, bind, and consume for an exclusive queue on a single connection.
- Enable AMQP heartbeats (10-30s) and TCP keepalive so dead owners are detected quickly and locks release.
- Treat exclusive queues as ephemeral: assume they vanish on disconnect and recreate them on reconnect instead of reattaching.
- For shared reply queues across many workers, use a normal (non-exclusive) durable queue with a stable name, or RabbitMQ’s direct reply-to (
amq.rabbitmq.reply-to) feature. - Add jittered reconnect backoff so a flapping client does not repeatedly race its own stale lock.
Related Errors
NOT_FOUND - no queue '...'— the exclusive queue was already auto-deleted when its owner disconnected; you tried to use it from a new connection.PRECONDITION_FAILED - inequivalent arg 'exclusive'— you redeclared an existing queue with a different exclusive flag.RESOURCE_LOCKEDon a single active consumer queue — a second consumer attached to a queue declared withx-single-active-consumeror exclusive consume.CHANNEL_ERRORafter a closed channel — frequently follows the same reconnect race that triggers resource lock issues.
Frequently Asked Questions
Can two connections share an exclusive queue? No. Exclusivity means exactly one connection may use the queue. If you need shared access, use a non-exclusive queue.
Why does the error persist for a few seconds after my client crashes? The broker only releases the lock once it detects the connection is dead. Without heartbeats this can take a minute or more. Enable heartbeats to shorten it.
Should exclusive queues be durable? There is no point — an exclusive queue is deleted when its connection closes, so it cannot outlive a restart regardless of the durable flag.
Is RESOURCE_LOCKED ever caused by the same connection? A single connection can declare and reuse its own exclusive queue freely. The error only fires when a different connection (including a reconnected one) touches it.
How do I avoid name collisions entirely?
Declare exclusive queues with an empty name and use the server-assigned amq.gen-... name the broker returns. See more fixes in the RabbitMQ guides.
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.