You add rabbitmq to a Compose file, point Celery or Spring AMQP at amqp://guest:guest@localhost:5672/, and the client dies with Connection refused. Or the TCP path works and you still get ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. The broker log may say user 'guest' can only connect via localhost, or invalid credentials, or nothing useful while your new RABBITMQ_DEFAULT_PASS is ignored.
This guide reproduces those failures with rabbitmq:4.4.0-management-alpine and a small Pika 1.3.2 client on the same Compose network, then fixes them. Every error string and log line below comes from that lab run on November 6, 2026. The Stack Overflow question ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN had 370,994 views that day, Connecting to RabbitMQ container with docker-compose had 50,479, and Rabbitmq - Docker connection refused on port 5672 had 35,539.
The short version:
- From another container,
localhostis that container. Use the Compose service name, for examplerabbitmq. -
ACCESS_REFUSEDwith PLAIN is the same client text for wrong passwords and for the guest loopback rule. Read the broker log line under it. - The official Docker image sets
loopback_users.guest = false, so guest from a peer container often works. Bare-metal RabbitMQ and a restored loopback config refuse guest from peers. - Set
RABBITMQ_DEFAULT_USERandRABBITMQ_DEFAULT_PASSon first boot. Changing them later does nothing if the data volume already exists. - Wait for a real healthcheck before starting the app.
depends_onalone is not enough.
Table of contents
Fix Connection refused to port 5672
Start with the map. Match the message you see to the cause and the fix:
Don't connect to localhost from the app container
The lab started with stock RabbitMQ and no custom user:
services: rabbitmq: image: rabbitmq:4.4.0-management-alpine hostname: rabbitmq A Pika client on the same Compose network played the app. With RMQ_HOST=localhost it never reached RabbitMQ:
client hostname='b1ce59b7a70e' connecting host='localhost' port=5672 user='guest' vhost='/' tcp connect to localhost:5672 failed: [Errno 111] Connection refused FAIL AMQPConnectionError: ConnectionRefusedError(111, 'Connection refused') Each container has its own loopback interface, so localhost inside the app is the app. RabbitMQ listens in the rabbitmq service. Set the host to rabbitmq (or whatever you named the service), for example amqp://labuser:secret@rabbitmq:5672/. The Redis guide and the MySQL guide show the same mistake for those databases.
From the Docker host itself you also need a published port. Without ports, a host tool cannot reach 5672. Add ports: ["127.0.0.1:5672:5672"] if a process on the host must talk AMQP. Other Compose services do not need that mapping.
Wait until the listener is ready
depends_on: [rabbitmq] only waits for the container process to start. In the lab, an immediate connect right after docker compose up -d still got Connection refused on rabbitmq:5672. After the healthcheck flipped to healthy, the same client opened AMQP and published a message. Use a healthcheck and condition: service_healthy, the pattern also used in the Umami guide with PostgreSQL:
services: rabbitmq: image: rabbitmq:4.4.0-management-alpine healthcheck: test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"] interval: 5s timeout: 10s retries: 12 start_period: 15s app: image: your-app:tag depends_on: rabbitmq: condition: service_healthy Fix ACCESS_REFUSED for the guest user
Read the broker log, not only the client text
The client message is almost always:
ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile. That one string covers several causes. The broker log names the real one. With a wrong password the lab logged PLAIN login refused: user 'guest' - invalid credentials. With the guest loopback rule restored it logged PLAIN login refused: user 'guest' can only connect via localhost.
Guest loopback on bare metal vs the Docker image
The RabbitMQ access control docs state the product default: "By default, the guest user is prohibited from connecting from remote hosts. It can only connect over a loopback interface (localhost)."
The official Docker image changes that for Compose peers. In rabbitmq:4.4.0-management-alpine, /etc/rabbitmq/conf.d/10-defaults.conf contains this setting (the image file comments it with ##, shown here with #):
# allow access to the guest user from anywhere on the network loopback_users.guest = false So a stock image often accepts guest from another container on the Compose network. That surprises people who paste bare-metal advice into a Docker setup, and the reverse also happens: if you restore the product default, guest from a peer fails again.
The lab copied loopback_users.guest = true into conf.d/20-loopback.conf and rebuilt a thin image on top of rabbitmq:4.4.0-management-alpine. From a peer container, guest then failed with ACCESS_REFUSED. The broker said:
PLAIN login refused: user 'guest' can only connect via localhost The same guest credentials from 127.0.0.1 inside the RabbitMQ network namespace opened AMQP successfully.
Do not "fix" this by setting loopback_users = none in production. Create a non-guest user instead. The docs call remote guest access a danger zone for a reason.
Fix DEFAULT_USER that never changes
Seed a user on first boot
On an empty data directory, the image reads RABBITMQ_DEFAULT_USER and RABBITMQ_DEFAULT_PASS and creates that administrator. The lab used:
services: rabbitmq: image: rabbitmq:4.4.0-management-alpine hostname: rabbitmq environment: RABBITMQ_DEFAULT_USER: labuser RABBITMQ_DEFAULT_PASS: Lab-Pass-4821 ports: - "127.0.0.1:5672:5672" - "127.0.0.1:15672:15672" healthcheck: test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"] interval: 5s timeout: 10s retries: 12 start_period: 15s volumes: - rmq-data:/var/lib/rabbitmq volumes: rmq-data: After the container became healthy, rabbitmqctl list_users showed only labuser with the administrator tag. The Pika client with those credentials published and consumed a durable queue message. guest/guest then returned ACCESS_REFUSED with invalid credentials. The management HTTP API on 127.0.0.1:15672 answered 200 for labuser and reported rabbitmq_version 4.4.0.
A named volume keeps the first password
The image stores users in /var/lib/rabbitmq. If you change RABBITMQ_DEFAULT_PASS in Compose and recreate the container with the same named volume, the env vars do not rewrite the existing user. That is the core of docker-library/rabbitmq#150 (29 comments): people edit the password in .env, restart, and still get ACCESS_REFUSED.
In the lab, the volume kept Lab-Pass-4821. After switching the env to New-Pass-9999, the new password failed:
FAIL ProbableAuthenticationError: ConnectionClosedByBroker: (403) 'ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.' The broker logged PLAIN login refused: user 'labuser' - invalid credentials. The old password still opened AMQP.
To rotate credentials on purpose, change the password with rabbitmqctl change_password, or remove the volume and accept a wipe of queues and users, then boot once with the new env. The PostgreSQL password guide and the MongoDB auth guide hit the same first-boot-vs-volume pattern.
A Compose file that works
Put the service name, a non-guest user, a healthcheck, and a volume together:
services: rabbitmq: image: rabbitmq:4.4.0-management-alpine hostname: rabbitmq environment: RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:?set RABBITMQ_DEFAULT_USER in .env} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:?set RABBITMQ_DEFAULT_PASS in .env} ports: - "127.0.0.1:5672:5672" - "127.0.0.1:15672:15672" healthcheck: test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"] interval: 5s timeout: 10s retries: 12 start_period: 15s volumes: - rmq-data:/var/lib/rabbitmq app: image: your-app:tag environment: AMQP_URL: amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672/ depends_on: rabbitmq: condition: service_healthy volumes: rmq-data: RABBITMQ_DEFAULT_USER=labuser RABBITMQ_DEFAULT_PASS=replace-me-with-a-long-secret Point every client at host rabbitmq, not localhost. Drop the ports block if nothing on the host needs AMQP or the management UI. Keep 127.0.0.1 when you do publish, the same habit as in the Portainer guide when you bind admin ports to the host loopback only.
Check it
$ docker compose up -d $ docker compose ps # rabbitmq health: healthy $ docker compose exec rabbitmq rabbitmqctl list_users Listing users ... user tags labuser [administrator] $ curl -sS -u labuser:replace-me-with-a-long-secret http://127.0.0.1:15672/api/overview | head -c 80 If the app still fails, read docker compose logs rabbitmq for the PLAIN login refused line before you change more config.
FAQ
Connection refused
Why does RabbitMQ refuse connections between Docker Compose containers?
Usually the app uses localhost or 127.0.0.1, which is its own container. Use the Compose service name, such as rabbitmq. If the host is already correct, the broker may not be listening yet. Add a rabbitmq-diagnostics -q ping healthcheck and depends_on with condition: service_healthy.
How do I connect to RabbitMQ in Docker from the host machine?
Publish the port, for example ports: ["127.0.0.1:5672:5672"], and connect to 127.0.0.1:5672 with a user that exists in the broker. Without ports, the host gets Connection refused. Other containers on the Compose network do not need a published port.
ACCESS_REFUSED and guest
Why do I get ACCESS_REFUSED with guest and PLAIN from another container?
Check the broker log. If it says user 'guest' can only connect via localhost, the loopback rule is on. Create a non-guest user with RABBITMQ_DEFAULT_USER and RABBITMQ_DEFAULT_PASS instead of reopening guest. If the log says invalid credentials, the password or username is wrong for the data in the volume.
Does the official RabbitMQ Docker image allow guest from other containers?
Yes, by default. rabbitmq:4.4.0-management-alpine ships loopback_users.guest = false in /etc/rabbitmq/conf.d/10-defaults.conf so Compose peers can use guest. That differs from bare-metal RabbitMQ, where guest is localhost-only. Still create a dedicated user for anything beyond a throwaway lab.
Users and volumes
Why does RABBITMQ_DEFAULT_PASS not change my password after a restart?
Those variables seed the default user only when the data directory is empty. A named volume keeps the first user and password. Change the password with rabbitmqctl change_password, or remove the volume and boot once with the new env if you accept wiping broker data.
How do I create a RabbitMQ user for Docker Compose the right way?
Set RABBITMQ_DEFAULT_USER and RABBITMQ_DEFAULT_PASS before the first start with an empty volume, or run rabbitmqctl add_user, set_user_tags, and set_permissions against a running node. Point clients at that user and the service name rabbitmq on port 5672.





