502 Bad Gateway in Nginx: Causes and How to Fix It
A 502 Bad Gateway page with nginx (or nginx/1.24.0, nginx/1.29.1 and so on) at the bottom means Nginx itself is running, but it is acting as a reverse proxy and the application behind it did not return a valid response. That application is called the upstream: usually PHP-FPM for WordPress and Laravel, a Node.js process, Gunicorn or uWSGI for Python, or a Docker container.
So the fix is almost never in Nginx alone. You need to find out why the upstream failed, and the Nginx error log tells you.
Step 1: Read the Nginx Error Log
Run this on the server, then reload the failing page and run it again:
sudo tail -n 50 /var/log/nginx/error.log
If your site has its own log, check the error_log line in its server block. Then match the message:
Error log message | What it means | Fix |
|---|
connect() failed (111: Connection refused) while connecting to upstream
| Nothing is listening on the upstream address | Fix 1 and 2 |
connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory)
| PHP-FPM socket path is wrong or PHP-FPM is stopped | Fix 3 |
connect() to unix:... failed (13: Permission denied)
| Nginx cannot open the socket or port | Fix 4 |
upstream sent too big header while reading response header from upstream
| Response headers (often cookies) exceed the buffer | Fix 5 |
upstream prematurely closed connection while reading response header
| The app crashed or was killed mid-request | Fix 6 |
no live upstreams while connecting to upstream
| Every server in an upstream block is marked down | Fix 1 and 2 for each backend |
Fix 1: The Upstream Is Not Running
Check the service behind Nginx:
# PHP (WordPress, Laravel)
sudo systemctl status php8.3-fpm
# Node.js under PM2
pm2 status
# Python under systemd
sudo systemctl status gunicorn
# Docker
docker ps -a
If it is stopped or restarting in a loop, start it and read its own logs (journalctl -u php8.3-fpm -n 50, pm2 logs, docker logs --tail 100 CONTAINER). Then test the upstream directly, bypassing Nginx:
curl -I http://127.0.0.1:3000
If that fails too, the problem is the app, not Nginx.
Fix 2: Nginx Points at the Wrong Address or Port
Compare what Nginx proxies to with what is actually listening:
sudo nginx -T | grep -E "proxy_pass|fastcgi_pass|uwsgi_pass"
sudo ss -tulpn
Common mismatches:
The app moved from port 3000 to 8080 but proxy_pass was not updated.
Docker: if Nginx runs on the host, proxy to the published port (127.0.0.1:8080 for -p 8080:80). If Nginx runs in a container, proxy to the service name on the shared network (http://app:3000), never localhost, which points at the Nginx container itself.
The app listens only on 127.0.0.1 inside its container. It must listen on 0.0.0.0 to be reachable from outside the container.
Fix 3: PHP-FPM Socket Path Mismatch
After a PHP upgrade the socket name changes (for example php8.1-fpm.sock to php8.3-fpm.sock) but the Nginx config still points at the old one. Check both sides:
grep -E "^listen" /etc/php/*/fpm/pool.d/www.conf
ls -l /run/php/
sudo nginx -T | grep fastcgi_pass
Make fastcgi_pass unix:/run/php/php8.3-fpm.sock; match the real socket, then reload.
Fix 4: Permission Denied on the Socket
The Nginx worker user (www-data on Ubuntu/Debian, nginx on RHEL, AlmaLinux and Oracle Linux) must be allowed to open the PHP-FPM socket. In the pool file set:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
Restart PHP-FPM. On RHEL-family systems with SELinux enforcing, Nginx is also blocked from connecting to network upstreams until you allow it:
sudo setsebool -P httpd_can_network_connect 1
Large cookies or many Set-Cookie headers (common with WooCommerce, SSO and some page builders) overflow the default buffers. Raise them in the server or location block:
# Reverse proxy (Node, Python, Docker)
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_busy_buffers_size 32k;
# PHP-FPM
fastcgi_buffer_size 32k;
fastcgi_buffers 16 16k;
Fix 6: The App Crashes or Runs Out of Memory
If the log says the upstream closed the connection, the process died while handling the request. The usual cause on small VPS plans is memory:
sudo dmesg -T | grep -i -E "killed process|out of memory"
If the kernel OOM killer is ending PHP-FPM, MySQL or Node, either reduce workers (pm.max_children for PHP-FPM), add swap, or move to a plan with more RAM. Our guide to fixing out-of-memory crashes with a swap file walks through the swap fix.
Apply Changes Safely
Always test before reloading so a typo does not take every site down:
sudo nginx -t && sudo systemctl reload nginx
See common Nginx errors and fixes for the other status codes.
502 vs 504 vs Cloudflare 502
502 Bad Gateway: the upstream refused the connection or returned something invalid. It usually appears instantly.
504 Gateway Timeout: the upstream accepted the request but did not answer in time. Look at slow queries or raise proxy_read_timeout / fastcgi_read_timeout.
Cloudflare-branded 502: if the error page shows the Cloudflare logo instead of nginx, Cloudflare could not get a valid response from your origin server at all. Check that the server is up and reachable on ports 80/443.
Frequently Asked Questions
What causes 502 Bad Gateway in Nginx?
Nginx is running as a reverse proxy, but the application behind it (PHP-FPM, Node.js, Gunicorn or a container) is stopped, listening on a different address, blocking the connection, crashing, or sending headers too large for the buffers.
Is a 502 error my fault or the website's?
As a visitor, it is almost always the website's server. Refreshing after a minute sometimes helps if the app was restarting. As the site owner, check the Nginx error log.
How do I fix 502 Bad Gateway with PHP-FPM?
Make sure PHP-FPM is running, that fastcgi_pass points at the real socket in /run/php/, and that the socket is owned by the Nginx user. Then run nginx -t and reload.
Why do I get 502 Bad Gateway with Docker and Nginx?
Usually because Nginx proxies to localhost from inside a container, or the app listens on 127.0.0.1 instead of 0.0.0.0. Proxy to the service name on a shared Docker network or to the published host port.
Does restarting Nginx fix a 502?
Rarely. Restart the upstream app instead; Nginx is only reporting the failure.
Rather Not Debug Nginx at 2 AM?
Every error in this guide is something a managed host fixes for you. RackUp IT managed hosting runs a tuned Nginx, PHP and caching stack with monitoring, backups and SSL handled, so you can spend your time on the site instead of the server.