Back to problems

problem hub

Read-only first

Nginx 502 Bad Gateway

Separate Nginx config, upstream listener, proxy target, and application failure before reloading services.

Safest first command

sudo nginx -t

Before you run this

Expected output: Nginx reports whether configuration syntax is OK or identifies the file and line with a problem.

When not to use it: Do not reload Nginx before testing config and confirming the upstream target. A reload can turn one bad vhost into a wider outage.

Expected output example

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

How to read the result

A successful config test means syntax is not the immediate blocker. Next, inspect proxy targets, listener state, and recent upstream logs.

What to check next

nginx -t reports a file and line error

Means: Config syntax or includes are invalid; a reload would be risky.

Next step: Inspect the reported file and line, then retest config before any reload.

Test Nginx Before Reload

Config test succeeds but upstream port is absent

Means: Nginx is valid, but the app or socket target is not listening.

Next step: Map proxy targets and listener state to identify the missing upstream.

Map Nginx Proxy Targets

Only some paths return 502

Means: The failing location may route to a specific upstream or app endpoint.

Next step: Group recent 5xx responses by path before changing global config.

Group Server Errors by URL Path

Test Nginx and find the upstream

A 502 usually means Nginx could not talk to the upstream. Prove config validity, then map proxy targets and listener state.

  1. sudo nginx -t
  2. grep -RInE 'proxy_pass|fastcgi_pass|uwsgi_pass' /etc/nginx 2>/dev/null
  3. ss -ltnp

Use logs to confirm the failing path

Group 5xx responses by URL path and inspect recent service logs for the upstream process.

Upstream decision tree

A 502 is usually a broken handoff. Prove whether Nginx config is valid, the upstream listener exists, the proxy target is correct, socket permissions allow access, or the application is failing after startup.

  1. sudo nginx -t
  2. grep -RInE 'proxy_pass|fastcgi_pass|uwsgi_pass' /etc/nginx 2>/dev/null
  3. ss -ltnp
  4. journalctl -u nginx -b --no-pager | tail -80
  5. journalctl -u app -b --no-pager | tail -80

Bad fixes to avoid

Do not reload before nginx -t succeeds, kill the upstream process without knowing its supervisor, rewrite proxy targets before reading config, or chmod a Unix socket path before proving the service user.

Common causes

  • Upstream service is not listening
  • Wrong proxy_pass host or port
  • Unix socket path or permission problem
  • Application crash or timeout
  • Nginx config syntax error before reload

What not to change yet

  • Do not reload before nginx -t succeeds.
  • Do not kill the upstream process until you know whether a supervisor owns it.
  • Do not rewrite proxy config before checking the current target.
  • Do not chmod socket directories before confirming the Nginx and app users.
  • Do not clear application logs before reading the first upstream error.

Stop and escalate if

  • Reloading or restarting Nginx or the upstream service would interrupt active users.
  • The upstream is a database-backed app and the failure may be a deployment or data issue.
  • You are editing production virtual hosts, TLS config, or proxy targets without a rollback path.

platform notes

Distro and service notes

systemd

Use journalctl for both nginx and the upstream service when systemd manages them.

Docker

Check published ports and container health before editing Nginx.

Permissions

Unix socket upstreams can fail because Nginx cannot access the socket directory.

supporting commands

Command path