The 502 Bad Gateway error is one of the most common and frustrating errors you'll encounter when running nginx as a reverse proxy. Your website is down, users can't access it, and you need to fix it fast.
In this comprehensive guide, I'll show you exactly how to diagnose and fix 502 errors, whether you're running PHP-FPM, Node.js, Python, or any other upstream backend.
What Does 502 Bad Gateway Mean?
A 502 error means nginx successfully received your request, but when it tried to forward it to your backend application (the "upstream"), something went wrong:
- The upstream server isn't running
- The upstream server refused the connection
- The upstream server took too long to respond
- Network issues between nginx and the upstream
Solution 1: Check if Your Backend Service is Running
The #1 cause of 502 errors is that your backend application simply isn't running. Let's check the most common services:
For PHP-FPM:
sudo systemctl status php8.1-fpm # Adjust version number
sudo systemctl start php8.1-fpm
sudo systemctl enable php8.1-fpm
For Node.js/PM2:
pm2 status
pm2 restart app-name
For Python/Gunicorn:
sudo systemctl status gunicorn
sudo systemctl start gunicorn
For Docker containers:
docker ps # Check if container is running
docker logs container-name # Check for errors
docker restart container-name
sudo journalctl -u php8.1-fpm -n 50
Solution 2: Verify Upstream Connection Settings
Your nginx configuration must point to the correct socket or port where your backend is listening.
Checking Nginx Upstream Configuration:
sudo nano /etc/nginx/sites-available/your-site
Common configurations:
For PHP-FPM (Unix socket):
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
For PHP-FPM (TCP socket):
fastcgi_pass 127.0.0.1:9000;
For Node.js/Express:
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
Verify the socket/port matches:
For Unix sockets:
ls -l /run/php/php8.1-fpm.sock # Should exist
sudo chmod 666 /run/php/php8.1-fpm.sock # If permission denied
For TCP ports:
sudo ss -tlnp | grep 3000 # Replace 3000 with your port
curl http://localhost:3000 # Test if backend responds
Solution 3: Increase Timeout Values
If your application takes a long time to process requests (complex database queries, API calls, large file processing), nginx might timeout before getting a response.
Add these to your nginx configuration:
location / {
proxy_pass http://localhost:3000;
# Increase timeouts
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
}
For PHP-FPM:
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
# Increase PHP timeouts
fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_connect_timeout 300;
}
Then reload nginx:
sudo nginx -t # Test configuration
sudo systemctl reload nginx
Solution 4: Check Upstream Server Logs
Your backend might be crashing or returning errors. Check the logs:
PHP-FPM errors:
sudo tail -f /var/log/php8.1-fpm.log
sudo journalctl -u php8.1-fpm -f
Node.js with PM2:
pm2 logs app-name
pm2 logs --err # Only errors
Python/Gunicorn:
sudo journalctl -u gunicorn -f
tail -f /var/log/gunicorn/error.log
Nginx error logs:
sudo tail -f /var/log/nginx/error.log
• "Connection refused" = Backend isn't running
• "No such file or directory" = Unix socket path is wrong
• "Upstream timed out" = Increase timeout values
• "Permission denied" = Fix socket file permissions
Solution 5: Fix PHP-FPM Pool Configuration
If you're using PHP-FPM, the pool might be overwhelmed or misconfigured.
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
Key settings to check:
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
; Make sure the listen matches your nginx config:
listen = /run/php/php8.1-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
After changes:
sudo systemctl restart php8.1-fpm
sudo systemctl reload nginx
Solution 6: Check System Resources
Your server might be out of memory or CPU resources, causing the backend to fail.
# Check memory usage
free -h
# Check CPU and processes
top
# Check disk space
df -h
# Check for OOM (Out of Memory) killer
sudo dmesg | grep -i "killed process"
If you're out of resources:
- Restart services to free memory:
sudo systemctl restart php8.1-fpm nginx - Optimize your application (reduce memory usage)
- Upgrade your VPS plan
- Enable swap memory
Stop Wrestling with Nginx Configs - Let VPS Commander Help
Debugging 502 errors, editing config files, and restarting services is tedious. VPS Commander gives you pre-built workflows for managing nginx, checking logs, and monitoring services - all with one click. No terminal required.
Start Free - Fix Errors FasterAdvanced Debugging: Reading Nginx Error Logs
Enable detailed upstream debugging in nginx:
error_log /var/log/nginx/error.log debug;
Then watch the logs while reproducing the error:
sudo tail -f /var/log/nginx/error.log
Look for lines containing "upstream" - they'll tell you exactly what went wrong.
Prevention: Avoiding 502 Errors
- Set up monitoring: Use UptimeRobot or similar to alert you immediately when 502s occur
- Enable service auto-restart: Configure systemd to restart crashed services automatically
- Monitor resources: Set up alerts for high memory/CPU usage before they cause issues
- Test configurations: Always run
nginx -tbefore reloading nginx - Keep backups of working configs: Before making changes, backup your nginx configs
Quick Reference Checklist
- ✅ Is the backend service running? (
systemctl status service-name) - ✅ Does the upstream configuration match the backend? (socket path or port)
- ✅ Are timeout values sufficient?
- ✅ What do the backend logs show? (
journalctl -u service-name) - ✅ What do nginx error logs show? (
tail /var/log/nginx/error.log) - ✅ Are there resource issues? (
free -h,top) - ✅ Can you curl the backend directly? (
curl http://localhost:port)
Conclusion
502 Bad Gateway errors are frustrating, but they're almost always caused by one of these issues:
- Backend service not running (most common)
- Incorrect upstream configuration
- Timeout values too low
- Resource exhaustion (RAM/CPU)
By systematically checking each potential cause in this guide, you should be able to identify and fix the issue. Remember: the error logs are your best friend - they'll tell you exactly what's wrong.