Common Issues

502 / 503 / 504: Diagnosis and Fix

How to diagnose and fix HTTP 502, 503, and 504 errors on Nginx and Apache

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:

  • upstream timed out
  • connect() failed
  • recv() failed
  • broken pipe

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.


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

On this page