Express.js 502 Bad Gateway behind nginx — complete fix
TL;DR
How to diagnose and fix 502 Bad Gateway errors when running Express.js behind an nginx reverse proxy.
Key facts
- Topic
- Production error triage
- Stack
- Express.js / nginx / Linux
TL;DR
A 502 Bad Gateway from nginx in front of Express.js means nginx received an invalid response from the upstream Express process — or no response at all. The Express process has either crashed, is too slow to respond, or is not listening on the expected address.
Common causes
- Express process crashed and has not restarted (check PM2 or systemd)
- Express is listening on a different port than nginx expects
- The
proxy_passtarget useshttp://localhost:3000but the app binds to a Unix socket (or vice versa) - Upstream timeouts — Express takes longer than nginx's
proxy_read_timeout - The app ran out of memory and was killed by the OOM killer
Diagnosis workflow
Check if the Express process is alive:
pm2 status
# or
systemctl status my-express-app
Verify it is listening on the expected port:
ss -tlnp | grep :3000
Review nginx error logs for the specific upstream error:
tail -100 /var/log/nginx/error.log
Look for upstream prematurely closed connection, connect() failed, or upstream timed out.
Fix the nginx configuration
Ensure your upstream block matches where Express actually listens:
upstream express_app {
server 127.0.0.1:3000;
keepalive 64;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://express_app;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 60s;
proxy_connect_timeout 10s;
}
}
Timeout alignment
Express, PM2, and nginx must agree on timeouts. If your Express route takes 30 seconds to respond, set proxy_read_timeout to at least 35 seconds. Ideally, move slow work to a background job queue so HTTP responses stay fast.
Where Reflex helps
Reflex correlates nginx 502 errors with upstream process health. When it detects a 502 spike, it checks whether the Express process is running, restarts it if needed, verifies the 502 rate drops, and alerts your team with a full incident timeline. See How it works.