Error Medic

502 Bad Gateway Error: Complete Troubleshooting Guide for Web Servers and Load Balancers

Fix 502 bad gateway errors on nginx, Apache, AWS ALB, and Cloudflare. Step-by-step debugging with log analysis and proven solutions.

Last updated:
Last verified:
1,869 words
Key Takeaways
  • Upstream server failures (PHP-FPM crashes, database timeouts) cause 80% of 502 errors
  • Proxy configuration issues including timeout settings and connection limits are common culprits
  • Network connectivity problems between proxy and backend servers trigger gateway errors
  • Check upstream server status first, then examine proxy logs, finally verify network connectivity
  • Most 502 errors resolve by restarting upstream services or adjusting timeout configurations
502 Bad Gateway Fix Approaches Compared
MethodWhen to UseTimeRisk
Restart upstream servicesService crashes or memory issues1-2 minutesLow
Increase timeout valuesSlow backend responses5 minutesLow
Fix proxy configurationMisconfigured upstream blocks10-15 minutesMedium
Scale backend resourcesHigh traffic overload15-30 minutesMedium
Network troubleshootingConnection refused errors30+ minutesHigh

Understanding the 502 Bad Gateway Error

A 502 Bad Gateway error occurs when a proxy server (nginx, Apache, load balancer) receives an invalid or no response from an upstream server. Unlike 503 Service Unavailable errors that indicate temporary overload, 502 errors specifically point to communication failures between proxy and backend services.

The error manifests differently across platforms:

  • nginx: "502 Bad Gateway" with "upstream prematurely closed connection" in logs
  • Apache: "502 Proxy Error" with "Error reading from remote server"
  • AWS ALB: "502 Bad Gateway" with target health check failures
  • Cloudflare: "Bad gateway" with "Error 502" and ray ID for tracking

Common Root Causes

Upstream Service Failures (60% of cases)

  • PHP-FPM process crashes or memory exhaustion
  • Application server timeouts (Node.js, Python, Ruby)
  • Database connection pool exhaustion
  • Out of memory conditions killing backend processes

Proxy Configuration Issues (25% of cases)

  • Incorrect upstream server addresses or ports
  • Timeout values too low for slow backend responses
  • Connection limits exceeded
  • SSL/TLS handshake failures between proxy and backend

Network Connectivity Problems (15% of cases)

  • Firewall blocking connections between proxy and backend
  • DNS resolution failures for upstream hostnames
  • Network partitions or routing issues
  • Port binding conflicts

Step 1: Quick Diagnostic Commands

Start with these immediate checks to identify the failure point:

# Check if upstream services are running
sudo systemctl status nginx
sudo systemctl status php8.1-fpm
sudo systemctl status mysql

# Verify network connectivity to backend
telnet backend-server 8080
nc -zv backend-server 3306

# Check recent error logs
sudo tail -f /var/log/nginx/error.log
sudo journalctl -u php8.1-fpm -f

Step 2: nginx 502 Bad Gateway Troubleshooting

Identify the Upstream Issue

Examine nginx error logs for specific error patterns:

# Look for upstream connection errors
sudo grep "upstream" /var/log/nginx/error.log | tail -20

# Common error patterns:
# "connect() failed (111: Connection refused)"
# "upstream prematurely closed connection"
# "upstream timed out (110: Connection timed out)"

Fix PHP-FPM Related 502 Errors

Most nginx 502 errors stem from PHP-FPM issues:

# Check PHP-FPM status and restart if needed
sudo systemctl status php8.1-fpm
sudo systemctl restart php8.1-fpm

# Monitor PHP-FPM processes
sudo tail -f /var/log/php8.1-fpm.log

# Check PHP-FPM pool configuration
sudo nano /etc/php/8.1/fpm/pool.d/www.conf

Key PHP-FPM settings to verify:

; Increase max children if getting connection refused
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

; Increase memory limit if processes are being killed
memory_limit = 256M

Adjust nginx Timeout Settings

Increase timeout values for slow backends:

# In /etc/nginx/sites-available/your-site
server {
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_read_timeout 300;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
    }
    
    # For reverse proxy setups
    location / {
        proxy_pass http://backend;
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}

Step 3: Apache 502 Proxy Error Resolution

ProxyPass Configuration Issues

# Check current proxy configuration
sudo apache2ctl -S

# Common fix for ProxyPass timeout issues
<VirtualHost *:80>
    ProxyPass /app/ http://backend:8080/
    ProxyPassReverse /app/ http://backend:8080/
    
    # Increase timeout values
    ProxyTimeout 300
    
    # Connection pool settings
    ProxySet connectiontimeout=30
    ProxySet retry=300
</VirtualHost>

Enable and Check Apache Proxy Modules

# Enable required proxy modules
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo systemctl restart apache2

# Check if modules are loaded
apache2ctl -M | grep proxy

Step 4: AWS Application Load Balancer 502 Errors

Target Health Check Failures

AWS ALB returns 502 when all targets are unhealthy:

# Check target group health
aws elbv2 describe-target-health --target-group-arn arn:aws:elasticloadbalancing:region:account:targetgroup/name

# Common issues:
# - Security group blocking health check port
# - Health check path returning non-2xx status
# - Target instances stopped or terminated

Security Group Configuration

Ensure proper inbound rules:

{
    "IpPermissions": [{
        "IpProtocol": "tcp",
        "FromPort": 80,
        "ToPort": 80,
        "UserIdGroupPairs": [{
            "GroupId": "sg-alb-security-group-id"
        }]
    }]
}

Application Response Issues

Check if your application is properly handling requests:

# Test health check endpoint directly
curl -v http://instance-private-ip/health

# Check application logs for errors
sudo journalctl -u your-app-service -f

Step 5: Cloudflare 502 Bad Gateway

Origin Server Connectivity

# Verify origin server is accessible
curl -H "Host: yourdomain.com" http://origin-server-ip/

# Check if origin is returning valid responses
curl -I http://your-origin-server.com

SSL/TLS Issues

Cloudflare 502 often indicates SSL problems:

# Test SSL connection to origin
openssl s_client -connect origin-server:443 -servername yourdomain.com

# Common fixes:
# 1. Ensure SSL certificate is valid on origin
# 2. Set Cloudflare SSL mode to "Full" instead of "Full (strict)"
# 3. Check if origin supports SNI

Step 6: Database Connection Issues

Database connection problems frequently cause 502 errors:

# Check MySQL connection limits
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"
mysql -u root -p -e "SHOW STATUS LIKE 'Connections';"

# Monitor current connections
mysql -u root -p -e "SHOW PROCESSLIST;"

# Increase max_connections if needed
# Add to /etc/mysql/mysql.conf.d/mysqld.cnf:
# max_connections = 200

Connection Pool Configuration

For application servers, verify connection pool settings:

// Node.js example
const mysql = require('mysql');
const pool = mysql.createPool({
    connectionLimit: 10,
    host: 'localhost',
    user: 'dbuser',
    password: 'dbpass',
    database: 'mydb',
    acquireTimeout: 60000,
    timeout: 60000
});

Step 7: Memory and Resource Issues

Check System Resources

# Monitor memory usage
free -h
top -o %MEM

# Check disk space
df -h

# Monitor I/O wait
iostat -x 1

# Check for OOM killer activity
sudo dmesg | grep -i "killed process"
sudo journalctl -k | grep -i "oom"

Increase Resource Limits

# Increase PHP memory limit
sudo nano /etc/php/8.1/fpm/php.ini
# memory_limit = 512M

# Increase nginx worker connections
sudo nano /etc/nginx/nginx.conf
# worker_connections 1024;

# Restart services
sudo systemctl restart php8.1-fpm nginx

Advanced Debugging Techniques

Network Packet Analysis

# Capture traffic between proxy and upstream
sudo tcpdump -i any -w 502-debug.pcap host backend-server and port 8080

# Analyze with wireshark or tcpdump
tcpdump -r 502-debug.pcap -A

Stress Testing

# Test with concurrent requests to identify breaking point
ab -n 1000 -c 50 http://your-site.com/

# Monitor during load test
watch -n 1 'ps aux | grep php-fpm | wc -l'

Prevention Strategies

Monitoring and Alerting

Set up monitoring for early detection:

# Create health check script
#!/bin/bash
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/health)
if [ $response -ne 200 ]; then
    echo "Health check failed with code: $response"
    # Send alert
fi

Graceful Degradation

Implement circuit breakers and fallback mechanisms:

# nginx upstream with fallback
upstream backend {
    server backend1:8080 max_fails=3 fail_timeout=30s;
    server backend2:8080 max_fails=3 fail_timeout=30s;
    server backup-server:8080 backup;
}

Capacity Planning

Regularly review and adjust resource allocation based on traffic patterns and growth projections.

Frequently Asked Questions

bash
#!/bin/bash
# 502 Bad Gateway Diagnostic Script
# Run this script to quickly identify common 502 error causes

echo "=== 502 Bad Gateway Diagnostic ==="
echo

# Check web server status
echo "[1] Checking web server status..."
for service in nginx apache2 httpd; do
    if systemctl is-active --quiet $service; then
        echo "✓ $service is running"
        WEB_SERVER=$service
        break
    fi
done

# Check upstream services
echo
echo "[2] Checking upstream services..."
for service in php8.1-fpm php8.0-fpm php7.4-fpm mysql mariadb postgresql; do
    if systemctl is-active --quiet $service; then
        echo "✓ $service is running"
    elif systemctl list-unit-files | grep -q $service; then
        echo "✗ $service is installed but not running"
        echo "   Try: sudo systemctl start $service"
    fi
done

# Check recent error logs
echo
echo "[3] Recent error log entries..."
if [ "$WEB_SERVER" = "nginx" ]; then
    echo "--- nginx errors ---"
    sudo tail -n 5 /var/log/nginx/error.log 2>/dev/null | grep -E "(upstream|502|connect|timeout)"
fi

# Check resource usage
echo
echo "[4] Resource usage..."
echo "Memory: $(free -h | awk 'NR==2{printf "%.1f%% used\n", $3*100/$2}')"
echo "Disk: $(df -h / | awk 'NR==2{print $5 " used"}')"
echo "Load: $(uptime | awk -F'load average:' '{print $2}')"

# Check connectivity
echo
echo "[5] Testing connectivity..."
if command -v nc >/dev/null; then
    if nc -z localhost 80; then
        echo "✓ Port 80 is open"
    else
        echo "✗ Port 80 is not accessible"
    fi
fi

# Quick fixes suggestion
echo
echo "[6] Quick fix commands:"
echo "sudo systemctl restart nginx php8.1-fpm"
echo "sudo tail -f /var/log/nginx/error.log"
echo "sudo systemctl status php8.1-fpm"
echo
echo "For detailed troubleshooting, check:"  
echo "- /var/log/nginx/error.log"
echo "- /var/log/php*/fpm.log"
echo "- systemctl status [service-name]"
E

Error Medic Editorial

Our DevOps engineering team has collectively resolved thousands of production incidents across web servers, cloud platforms, and distributed systems. We specialize in rapid diagnosis and systematic troubleshooting of HTTP errors, performance issues, and infrastructure failures.

Sources

Related Articles in Other

Explore More browser Guides