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

RabbitMQ Error Guide: 'ACCESS_REFUSED - access to queue refused for user' Authorization Failure

Fix RabbitMQ ACCESS_REFUSED authorization errors: set correct configure/write/read permission regexes per vhost so users can declare, publish to, and consume resources.

  • #rabbitmq
  • #troubleshooting
  • #errors
  • #authorization

Exact Error Message

This ACCESS_REFUSED happens after a successful login. The user authenticated and was granted the vhost, but lacks permission to operate on a specific queue or exchange. It is an authorization failure (what you may do), not an authentication failure (who you are).

2026-06-29 10:27:13.904 [error] <0.27744.5> operation queue.declare caused a channel exception access_refused:
access to queue 'orders.events' in vhost 'prod' refused for user 'orders-svc'

Or on publish to an exchange:

2026-06-29 10:31:48.220 [error] <0.27801.5> operation basic.publish caused a channel exception access_refused:
access to exchange 'billing.topic' in vhost 'prod' refused for user 'orders-svc'

The client typically sees a closed channel with ACCESS_REFUSED - access to queue 'orders.events' in vhost 'prod' refused for user 'orders-svc'.

What the Error Means

RabbitMQ permissions are three regular expressions scoped per user per vhost: configure, write, and read. Each AMQP operation maps to one or more of these:

  • configure — declaring or deleting a queue/exchange (queue.declare, exchange.declare, queue.delete).
  • write — publishing to an exchange and binding a queue (basic.publish, queue.bind on the destination).
  • read — consuming, getting, purging, and binding (the source side of queue.bind, basic.consume, basic.get).

When the resource name does not match the relevant regex, the broker raises access_refused on that operation and closes the channel. The login succeeded, so this is purely about which resources the user’s permission regexes allow. An empty regex (^$) matches nothing and denies everything; .* matches everything.

Common Causes

1. Permissions too narrow for the resource name

A user granted configure on ^orders\. cannot declare events.dlq. The regex simply does not match the name the app uses.

2. Right vhost, wrong permission column

The user can declare a queue (configure) but not consume from it (read), or can read but not publish (write). Each operation needs its own column to match.

3. Empty permission strings

Created with set_permissions user "" "" "", the user can log in and select the vhost but is denied every operation.

4. Publishing/binding nuance

queue.bind checks write on the queue (destination) and read on the exchange (source). Granting only one side still fails the bind with access_refused.

5. Default exchange or amq.* resources

Publishing to a named exchange the user has no write on, or trying to configure reserved amq.* resources, triggers refusals even when the basic queue permissions look fine.

How to Reproduce the Error

Create a user with deliberately narrow permissions, then operate outside them:

# Set up a constrained user (admin action; shown for reproduction context)
rabbitmqctl add_user appuser 'S3cret!'
rabbitmqctl set_permissions -p prod appuser '^orders\.' '^orders\.' '^orders\.'

# Now try to declare a queue outside the allowed prefix -> ACCESS_REFUSED
rabbitmqadmin -u appuser -p 'S3cret!' -V prod declare queue name=billing.events

The declare fails because billing.events does not match the ^orders\. configure regex, producing access to queue 'billing.events' in vhost 'prod' refused for user 'appuser'.

Diagnostic Commands

# Show the user's three permission regexes in each vhost
rabbitmqctl list_user_permissions orders-svc

# Show all users' permissions for a specific vhost
rabbitmqctl list_permissions -p prod

# Confirm topic-exchange authorisation (separate from configure/write/read)
rabbitmqctl list_topic_permissions -p prod

# Verify the user exists and its tags
rabbitmqctl list_users

# Tail the broker log for the exact refused operation and resource
sudo journalctl -u rabbitmq-server -f | grep -E 'access_refused|refused for user'

Step-by-Step Resolution

Step 1: Read the error precisely

Note three things from the log: the operation (queue.declare, basic.publish, etc.), the resource name and type (queue vs exchange), and the vhost and user. These map directly to which permission column to fix.

Step 2: Inspect current permissions

rabbitmqctl list_user_permissions orders-svc

Compare the configure/write/read regexes against the resource name in the error. An empty column or a non-matching prefix is your culprit.

Step 3: Grant the minimum matching permission

Re-run set_permissions with regexes that include the needed resources. Note this replaces all three columns, so include existing patterns too:

# configure  write  read
rabbitmqctl set_permissions -p prod orders-svc '^orders\.|^events\.' '^orders\.|^billing\.topic$' '^orders\.'

Step 4: Handle bind and topic specifics

For queue.bind failures, ensure write on the queue and read on the exchange. For topic exchanges with routing-key authorization, also set set_topic_permissions.

Step 5: Verify

Re-run the failing operation (or rabbitmqadmin declare/publish) as that user. The channel should stay open. Confirm with list_user_permissions that the regexes now cover every resource the app touches.

Prevention and Best Practices

  • Design a naming convention (e.g., per-team prefixes) and map permission regexes to it, so new resources fall inside existing grants.
  • Grant least privilege but anchor regexes carefully — remember set_permissions overwrites all three columns at once.
  • Distinguish authentication from authorization in alerting: “Login refused” is a credential problem; “access … refused for user” is a permissions problem.
  • Use list_topic_permissions for topic exchanges with routing-key restrictions; standard configure/write/read does not cover routing keys.
  • Keep permission changes in configuration management or definitions.json so they are reviewable and reproducible across environments.
  • For fast triage, the free incident assistant can map an access_refused line to the exact permission column to change.
  • ACCESS_REFUSED - Login was refused for user — authentication failure (wrong password / user), which happens before any permission check.
  • ACCESS_REFUSED - vhost '/' not found — the user has no access to (or the broker lacks) the vhost itself.
  • PLAIN login refused: user ... does not exist — the account is missing entirely.
  • operation ... caused a channel exception not_found — the resource does not exist, a different class from a permission denial.

See the RabbitMQ guides for the related auth errors.

Frequently Asked Questions

What is the difference between this and “Login was refused”? “Login was refused” is authentication — the broker rejected the credentials, so no connection is established. “access … refused for user” is authorization — login succeeded, but the user lacks configure/write/read permission on a specific resource.

Why can my user declare a queue but not consume from it? Declaring needs the configure permission; consuming needs read. They are separate regex columns. A user can match configure for a queue name yet have an empty or non-matching read regex.

Does set_permissions add to existing permissions? No. It replaces all three regexes for that user/vhost in one call. Always include the patterns you want to keep, or you will inadvertently revoke them.

Why does queue.bind fail with access_refused when declare works? Binding checks two permissions: write on the destination queue and read on the source exchange. Having configure (declare) rights does not grant either of those, so the bind is refused.

How do I authorize specific routing keys on a topic exchange? Use rabbitmqctl set_topic_permissions and inspect with list_topic_permissions. Routing-key-level authorization is a separate layer on top of the standard configure/write/read permissions.

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.