The Problem
When you put RabbitMQ's Management UI behind an nginx reverse proxy under a
sub-path like /rabbitmq/, queue detail pages and many API calls break silently.
The root cause: nginx normalizes the request URI before proxying. It decodes
%2F (the URL-encoded forward slash) into a literal /. RabbitMQ's Management
API uses %2F to represent the default virtual host (/) in API paths:
GET /api/queues/%2F/my-queue
When nginx decodes it:
GET /api/queues///my-queue ← broken
What Doesn't Work
The common advice of using merge_slashes off or a rewrite directive doesn't
fully solve this because nginx still normalizes $uri before forwarding.
The Fix
Use $request_uri inside an if block. Unlike $uri, $request_uri holds
the raw, undecoded URI exactly as the client sent it — nginx never touches it.
nginx
# RabbitMQ: API paths — use $request_uri to preserve %2F (never decoded by nginx)
location ~* ^/rabbitmq/api/ {
if ($request_uri ~* "^/rabbitmq/(.*)") {
proxy_pass http://rabbitmq:15672/$1;
}
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
# RabbitMQ: general UI (JS, CSS, static assets, non-API pages)
location ~* ^/rabbitmq/ {
rewrite ^/rabbitmq/(.*)$ /$1 break;
proxy_pass http://rabbitmq:15672;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
Top comments (0)