How to Fix 502 Bad Gateway in Nginx on Ubuntu 24.04 LTS
Quick Fix Summary
TL;DRRestart your PHP-FPM or upstream application service and verify the upstream server is reachable from Nginx.
A 502 Bad Gateway indicates Nginx successfully received a request but failed to get a valid response from its upstream server (e.g., PHP-FPM, Gunicorn, another backend). This is a proxy-level error, not a client-side issue.
Diagnosis & Causes
Recovery Steps
Step 1: Verify Upstream Service Status
First, confirm if your backend application or process manager is running.
sudo systemctl status php8.3-fpm
sudo systemctl status gunicorn
sudo ss -tlnp | grep :9000 Step 2: Restart the Upstream Service
If the service is down or unstable, restart it and check logs for crash reasons.
sudo systemctl restart php8.3-fpm
sudo journalctl -u php8.3-fpm --since "5 minutes ago" -f Step 3: Test Connectivity from Nginx to Upstream
Simulate Nginx's connection attempt to rule out network or permission issues.
# Test TCP connection (for port-based upstream)
sudo apt-get install -y netcat
nc -zv 127.0.0.1 9000
# Test Unix socket permissions
sudo ls -la /var/run/php/php8.3-fpm.sock Step 4: Check Nginx Error Logs for Specific Upstream Errors
Nginx logs the precise reason for the upstream failure. This is the most diagnostic step.
sudo tail -50 /var/log/nginx/error.log
# Look for lines containing 'connect() failed', 'upstream timed out', or 'Connection refused' Step 5: Adjust Nginx Proxy Timeouts
If logs show timeouts, increase proxy buffers and timeouts to handle slow backends.
# Edit your site configuration in /etc/nginx/sites-available/
sudo nano /etc/nginx/sites-available/your_site
# Inside the location block for PHP or proxy_pass, add:
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
fastcgi_read_timeout 300s;
# Test and reload Nginx
sudo nginx -t && \
sudo systemctl reload nginx Step 6: Inspect Upstream Server Resource Limits
PHP-FPM may hit `pm.max_children` or memory limits, causing it to reject connections.
sudo nano /etc/php/8.3/fpm/pool.d/www.conf
# Check and adjust: pm.max_children, pm.max_requests, php_admin_value[memory_limit]
sudo systemctl restart php8.3-fpm Architect's Pro Tip
"For intermittent 502s, monitor `netstat -s | grep 'listen'` for overflowed socket queues and increase the `net.core.somaxconn` kernel parameter."
Frequently Asked Questions
I restarted PHP-FPM and the 502 went away, but it came back hours later. What's wrong?
This points to a resource leak or gradual exhaustion. Your PHP-FPM `pm.max_requests` setting is likely too high or a memory leak in the application is causing workers to die. Lower `pm.max_requests` to recycle workers periodically and monitor PHP-FPM pool status with `sudo systemctl status php8.3-fpm`.
The Nginx error log says '111: Connection refused'. What does this mean?
This means Nginx tried to connect to the socket or port defined in `fastcgi_pass` or `proxy_pass` (e.g., 127.0.0.1:9000) and the operating system refused it. The upstream service is not listening on that port. Verify the service is running and the configuration points to the correct address.
Should I use a Unix socket or TCP port for PHP-FPM with Nginx?
For single-server setups, a Unix socket (`unix:/var/run/php/php8.3-fpm.sock`) is slightly faster and more secure as it avoids the network stack. For multi-server setups or containerized environments, a TCP port (`127.0.0.1:9000`) is necessary. Ensure socket file permissions allow the `www-data` user (Nginx) to read/write it.