Skip to content

/config/nginx/proxy-pass-trailing-slash

nginx proxy_pass with and without a trailing slash

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · nginx version: nginx/1.30.6updated 2026-10-20
tool
nginx
file
nginx.conf (location context)
key
proxy_pass
type
URL: protocol://host[:port][/uri]
default
none

Whether proxy_pass has a URI part decides what path the backend receives. Without a URI (proxy_pass http://127.0.0.1:3000;) nginx forwards the request URI unchanged. With a URI, even just /, nginx replaces the part of the request URI that matched the location prefix with that URI.

The four cases, with real requests

A Node.js backend prints the path it receives; nginx proxies to it from four locations:

bash
mkdir -p logs temp
cat > backend.js <<'EOF'
const s = require("http").createServer((req, res) => res.end(`backend saw ${req.url}\n`));
s.listen(3901, "127.0.0.1");
setTimeout(() => process.exit(0), 4000);
EOF
cat > nginx.conf <<'EOF'
pid logs/nginx.pid;
events {}
http {
  access_log off;
  server {
    listen 127.0.0.1:3902;
    location /no-slash/   { proxy_pass http://127.0.0.1:3901; }
    location /with-slash/ { proxy_pass http://127.0.0.1:3901/; }
    location /api/        { proxy_pass http://127.0.0.1:3901/v2/; }
    location /mixed       { proxy_pass http://127.0.0.1:3901/; }
  }
}
EOF
node backend.js &
nginx -p . -c nginx.conf -e logs/error.log &
sleep 1
for path in /no-slash/users /with-slash/users /api/users /mixed/users; do
  printf '%-18s -> ' "$path"; curl -s "http://127.0.0.1:3902$path"
done
nginx -p . -c nginx.conf -e logs/error.log -s stop

Output

/no-slash/users    -> backend saw /no-slash/users
/with-slash/users  -> backend saw /users
/api/users         -> backend saw /v2/users
/mixed/users       -> backend saw //users

Rule of thumb

locationproxy_passRequestBackend receives
/app/http://b:3000/app/users/app/users
/app/http://b:3000//app/users/users
/app/http://b:3000/v2//app/users/v2/users
/apphttp://b:3000//app/users//users (keep slashes consistent)

Inside regular-expression locations a URI part is not allowed at all; see proxy_pass cannot have URI part.

Sources