A 502 Bad Gateway from nginx means nginx is working fine — it is your upstream that failed. nginx tried to hand the request to your application (PHP-FPM, a Node process, gunicorn, another server) and got nothing usable back. So you debug the thing behind nginx, not nginx itself.
Always start with the error log
The log names the exact reason. Read it before touching config:
sudo tail -n 50 /var/log/nginx/error.logThe message points straight at the cause:
connect() failed (111: Connection refused)— the upstream is not running.no live upstreams— every backend nginx knows about is down.upstream timed out— the backend is alive but too slow.connect() to unix:/….sock failed— wrong socket path or permissions.
Cause 1: the upstream is not running
# pick the one you use
sudo systemctl status php8.3-fpm
sudo systemctl status your-node-app
sudo systemctl restart php8.3-fpmConfirm it is actually listening where nginx expects. If nginx proxies to 127.0.0.1:3000, that port must show up here:
sudo ss -tlnp | grep -E ':3000|php|fpm'Cause 2: wrong socket or port in the config
The fastcgi_pass or proxy_pass target must match what the backend binds. A PHP upgrade that changes the socket path (php8.2-fpm.sock → php8.3-fpm.sock) is a classic trigger:
grep -R "fastcgi_pass\|proxy_pass" /etc/nginx/
ls /run/php/ # what socket actually exists?Cause 3: the backend is too slow
If the log says timed out, the app works but exceeds nginx’s patience. Raise the timeout as a stopgap, but fix the slow code or add resources for a real cure:
# in the location or server block
proxy_read_timeout 120s;
# then
sudo nginx -t && sudo systemctl reload nginxCause 4: socket permissions
When nginx and the backend run as different users, nginx may not be allowed to open the socket. Align the FPM pool’s listen.owner/listen.group with the nginx user (often www-data), then restart both.
Persistent 502s under traffic often mean the server is simply undersized. A Hi-CPU KVM plan gives PHP-FPM and Node the headroom to keep responses inside nginx’s timeout window.
Frequently asked
Is a 502 nginx's fault?
No. nginx is working — it tried to pass the request to your backend (PHP-FPM, Node, etc.) and got nothing usable. Debug the upstream, not nginx.
Where do I find the actual cause?
In /var/log/nginx/error.log. The message names it: 'connection refused' (upstream down), 'upstream timed out' (too slow), or a socket-path error.
502s appear only under load — why?
Usually PHP-FPM running out of workers or the server running out of RAM. Check 'free -m' and the FPM pm.max_children setting before raising the timeout.