NGINX 502 Bad Gateway: five checks that find it
⏱️ 2 min read
What a 502 actually is
NGINX accepted your request, tried to forward it to proxy_pass, and the upstream refused, died mid-handshake, or stayed silent past the timeout. The fix is almost never in NGINX itself.
The five checks
- Can the upstream machine reach itself? On the box:
curl -v http://127.0.0.1:<app-port>/healthz. If this fails, NGINX is innocent. - Is the port right in the config?
grep proxy_pass /etc/nginx/*.conf. The classic: app listens on 3000, NGINX points at 8000. - Is the upstream process alive?
systemctl status <app>ordocker ps. Crashed workers and stopped containers are the #1 cause. - Is it listening on the interface NGINX uses? An app bound to
127.0.0.1behind a Docker bridge or a remote host IP will refuse the connection NGINX makes. Bind0.0.0.0(or the right interface) inside the container. - IPv6/localhost mismatch.
proxy_pass http://localhost:8080resolving to::1while the app is IPv4-only gives confusing 502s. Use127.0.0.1explicitly.
Timeout 502s
If the app takes 90s per request and proxy_read_timeout is the default 60s, slow requests turn into 502s. Raise proxy_read_timeout for that one location, not globally.
Fronting it
While the upstream is down, users see raw 502s. Putting a proxy layer with a friendly maintenance page in front helps brands more than it helps uptime. If the origin itself is the weak link, an edge location close to users gives you cleaner failover: Vultr's 32 locations make origin moves cheap. (Partner link.)