502 / 503 / 504: Diagnosis and Fix
Understanding the Errors
502 Bad Gateway The web server (Nginx/Apache) received an invalid response from the upstream application server (PHP-FPM, Node.js, Python app, etc.). The upstream is running but not responding correctly.
503 Service Unavailable The service is either completely down or too overloaded to handle requests. This can be due to rate limiting, resource exhaustion, or a deliberately disabled service.
504 Gateway Timeout The web server waited for a response from the upstream application but didn't receive it in time. The upstream is either hanging or responding too slowly.
Step 1: Check the Logs
Nginx Error Log
tail -f /var/log/nginx/error.log
Look for messages like:
Apache Error Log
tail -f /var/log/apache2/error.log
Always check logs first — the error message tells you exactly what's failing. Don't skip this step.
- upstream timed out
- connect() failed
- recv() failed
- broken pipe
Step 2: Verify Upstream Services Are Running
Check PHP-FPM
systemctl status php8.1-fpm
# or php8.0-fpm, php7.4-fpm, etc. depending on your version
Restart if needed:
systemctl restart php8.1-fpm
Check Application Services (Node, Python, etc.)
systemctl status your-app-name
ps aux | grep node
ps aux | grep python
Verify the service is bound to the expected port:
netstat -tlnp | grep LISTEN
# or with ss
ss -tlnp | grep LISTEN
Step 3: Test Upstream Directly
Try to connect to the upstream application directly from localhost:
# For PHP-FPM (usually port 9000)
curl -v http://127.0.0.1:9000
# For Node.js (common port 3000, 8080, etc.)
curl -v http://127.0.0.1:3000
# For Python app (common port 8000, 5000)
curl -v http://127.0.0.1:5000
If the connection is refused, the service isn't running or listening on that port.
Step 4: PHP-FPM Configuration Tuning
Edit /etc/php/8.1/fpm/pool.d/www.conf:
nano /etc/php/8.1/fpm/pool.d/www.conf
Key settings for 502 errors:
pm = dynamic
pm.max_children = 20 # Increase if you have RAM and heavy traffic
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 1000 # Prevent memory leaks
Reload PHP-FPM:
systemctl reload php8.1-fpm
Step 5: Nginx Upstream Timeouts
Edit your Nginx server block configuration (e.g., /etc/nginx/sites-available/default):
upstream backend {
server 127.0.0.1:9000;
}
server {
listen 80;
server_name example.com;
# For PHP-FPM (FastCGI)
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_connect_timeout 60s;
fastcgi_read_timeout 300s; # Increase for slow queries/processing
fastcgi_send_timeout 60s;
}
# For proxied applications (Node, Python, etc.)
location / {
proxy_pass http://backend;
proxy_connect_timeout 60s;
proxy_send_timeout 300s;
proxy_read_timeout 300s; # Increase for long-running requests
}
}
Test and reload:
nginx -t
systemctl reload nginx
Step 6: Check System Resources
High CPU, memory, or disk usage can cause 502/503/504 errors:
# Memory usage
free -h
# Disk usage
df -h
# CPU and process usage
top
# or
htop
If resources are maxed out:
- Reduce pool size or worker count
- Optimize database queries
- Enable caching (Redis, Memcached)
- Add more resources or upgrade your plan
Step 7: Diagnose 503 from Rate Limiting
Check Nginx configuration for limit_req_zone:
grep -r "limit_req" /etc/nginx/
Example rate limiting block that causes 503:
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
server {
location / {
limit_req zone=general burst=20 nodelay;
}
}
Adjust the rate or burst values if legitimate traffic is being blocked:
nginx -t && systemctl reload nginx
Quick Troubleshooting Checklist
- [ ] Check error logs (Nginx/Apache)
- [ ] Verify upstream service is running: systemctl status php8.1-fpm
- [ ] Test upstream directly: curl http://127.0.0.1:9000
- [ ] Check system resources: free -h, df -h, top
- [ ] Increase PHP-FPM pm.max_children if needed
- [ ] Increase timeout values in Nginx/Apache
- [ ] Check for rate limiting rules blocking traffic
- [ ] Restart services if changes were made: systemctl restart php8.1-fpm
Related articles
Locked Out of VPS
Complete guide to recover server access when locked out, with step-by-step instructions from VNC Console
Server Unreachable
What to do when server is not responding or you can't connect via SSH
Website Not Reachable
What to do when website is not responding, shows errors, or is unreachable
