Docs / Troubleshooting / Debug 502 Bad Gateway Errors Systematically

Debug 502 Bad Gateway Errors Systematically

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 535 views · 4 min read

A 502 Bad Gateway error means your reverse proxy (typically Nginx) received an invalid response from the upstream backend server. This is one of the most common web application errors and has many possible causes. This guide provides a systematic approach to debugging 502 errors.

Systematic Debugging Approach

# Step 1: Is the backend process running?
sudo systemctl status your-app
ps aux | grep your-app

# Step 2: Is the backend listening on the expected port?
sudo ss -tlnp | grep :8080

# Step 3: Can Nginx reach the backend?
curl -v http://127.0.0.1:8080/

# Step 4: Check Nginx error logs
sudo tail -50 /var/log/nginx/error.log
# Common 502-related errors:
# "connect() failed: Connection refused"  → backend not running
# "upstream timed out"                     → backend too slow
# "recv() failed: Connection reset"        → backend crashed
# "no live upstreams"                      → all backends are down

Backend Not Running

# Check service status and logs
sudo systemctl status your-app
sudo journalctl -u your-app -n 100

# Common causes:
# - Application crashed (check for segfaults, OOM kills)
# - Port conflict (another process took the port)
# - Configuration error preventing startup
# - Missing dependencies or environment variables

# Fix: Restart and monitor
sudo systemctl restart your-app
sudo journalctl -u your-app -f  # Watch logs in real-time

Backend Too Slow (Timeout)

# Nginx has a 60-second default proxy timeout
# If your backend takes longer, Nginx returns 502

# Increase timeouts
location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;
}

# But also investigate WHY the backend is slow
# - Database queries taking too long
# - External API calls timing out
# - Memory pressure causing GC pauses
# - Disk I/O bottleneck

PHP-FPM 502 Errors

# Check PHP-FPM is running
sudo systemctl status php8.3-fpm
sudo ss -tlnp | grep php

# Check PHP-FPM error log
sudo tail -50 /var/log/php8.3-fpm.log

# Common causes:
# 1. All workers busy (increase pm.max_children)
# 2. Worker crashed (check for segfaults)
# 3. Socket permission mismatch

# Fix: Match socket path and permissions
# In Nginx:
fastcgi_pass unix:/run/php/php8.3-fpm.sock;

# In PHP-FPM pool config:
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

# Increase workers
pm = dynamic
pm.max_children = 50
pm.start_servers = 10

sudo systemctl restart php8.3-fpm

Application Crashes Under Load

# Check for OOM kills
dmesg | grep -i "oom\|killed"
journalctl | grep -i "oom"

# Check memory usage
free -h
ps aux --sort=-%mem | head -10

# Check for rapid process restarts (crash loop)
journalctl -u your-app --since "10 minutes ago" | grep -c "Started\|Stopped"

# Increase restart delay to prevent rapid cycling
# In systemd service:
[Service]
Restart=on-failure
RestartSec=5
StartLimitBurst=5
StartLimitIntervalSec=60

Upstream Configuration Issues

# Verify Nginx upstream config
nginx -T | grep -A5 "upstream"

# Ensure proxy headers are set correctly
location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # Buffer settings
    proxy_buffering on;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
}

# Test configuration
sudo nginx -t
sudo systemctl reload nginx

Quick Checklist

  1. Is the backend process running? (systemctl status)
  2. Is it listening on the right port/socket? (ss -tlnp)
  3. Can you curl the backend directly? (curl localhost:8080)
  4. What does the Nginx error log say? (tail /var/log/nginx/error.log)
  5. Is the application crashing? (journalctl -u app)
  6. Is there a memory/resource issue? (free -h, top)

Best Practices

  • Always check Nginx error logs first — they tell you the specific upstream failure reason
  • Test the backend independently: curl localhost:PORT bypasses Nginx
  • Set up health checks in your Nginx upstream configuration
  • Monitor backend response times with $upstream_response_time in logs
  • Use process managers (systemd, PM2) that auto-restart crashed applications
  • Implement graceful degradation with Nginx's backup and fallback directives

Was this article helpful?