Error Medic

502 Bad Gateway Error: Complete Troubleshooting Guide

Fix 502 Bad Gateway errors fast. Step-by-step guide covering nginx, Apache, load balancers, and common causes with proven solutions.

Last updated:
Last verified:
1,600 words
Key Takeaways
  • 502 Bad Gateway occurs when upstream server fails to respond properly to proxy/gateway
  • Most common causes: server overload, connection timeout, misconfigured proxy settings
  • Quick fixes: restart web server, check upstream health, verify proxy configuration
  • Related errors 403/404/503/504 often indicate different infrastructure issues
  • SSL/TLS misconfigurations frequently trigger ERR_SSL_PROTOCOL_ERROR alongside 502s
502 Bad Gateway Fix Approaches Compared
MethodWhen to UseTimeRisk
Server RestartQuick temp fix, low traffic2-5 minLow
Proxy Config FixPersistent issues, config changes10-30 minMedium
Upstream Health CheckMultiple server setup5-15 minLow
Resource ScalingHigh traffic, performance issues15-60 minMedium
SSL/TLS ReconfigurationCertificate/encryption errors20-45 minHigh

Understanding 502 Bad Gateway Errors

A 502 Bad Gateway error occurs when a server acting as a gateway or proxy receives an invalid response from an upstream server. This is fundamentally different from other HTTP errors:

  • 403 Forbidden: Client lacks permission to access resource
  • 404 Not Found: Resource doesn't exist at specified URL
  • 503 Service Unavailable: Server temporarily unable to handle requests
  • 504 Gateway Timeout: Upstream server fails to respond within timeout period

The 502 error specifically indicates communication failure between proxy and backend server, making it a critical infrastructure issue requiring immediate attention.

Common 502 Bad Gateway Scenarios

Nginx Reverse Proxy Issues Nginx serving as reverse proxy encounters backend server problems:

2024/01/15 10:30:45 [error] 1234#0: *567 connect() failed (111: Connection refused) while connecting to upstream
2024/01/15 10:30:45 [error] 1234#0: *567 upstream prematurely closed connection while reading response header from upstream

Application Server Crashes PHP-FPM, Node.js, or Python applications crash while nginx attempts connection:

502 Bad Gateway
nginx/1.23.1

Load Balancer Failures AWS Application Load Balancer or Azure Application Gateway returns 502 when backend instances fail health checks.

Docker Container Issues Docker containers exit unexpectedly while nginx proxy attempts connection:

502 Bad Gateway
openresty/1.19.9.1

Step 1: Initial Diagnosis

Check Server Logs Immediately Start with web server error logs to identify root cause:

# Nginx error logs
sudo tail -f /var/log/nginx/error.log

# Apache error logs
sudo tail -f /var/log/apache2/error.log

# System logs for service failures
sudo journalctl -u nginx -f
sudo journalctl -u php7.4-fpm -f

Verify Upstream Service Status Check if backend services are running:

# Check process status
sudo systemctl status nginx
sudo systemctl status php7.4-fpm
sudo systemctl status mysql

# Check port availability
sudo netstat -tlnp | grep :9000  # PHP-FPM
sudo netstat -tlnp | grep :3000  # Node.js
sudo ss -tlnp | grep :8080       # Alternative check

Test Direct Backend Connection Bypass proxy to test backend directly:

# Test PHP-FPM socket
sudo -u www-data php-fpm -t

# Test application port directly
curl -v http://localhost:3000/health
curl -v http://127.0.0.1:8080/status

# Check database connectivity
mysqladmin -u root -p ping

Step 2: Nginx-Specific Troubleshooting

Common Nginx 502 Causes and Fixes

  1. PHP-FPM Not Running
# Restart PHP-FPM
sudo systemctl restart php7.4-fpm

# Check PHP-FPM configuration
sudo nginx -t
sudo php-fpm7.4 -t
  1. Incorrect Upstream Configuration
# Fix common nginx upstream config
upstream backend {
    server 127.0.0.1:9000;  # Correct PHP-FPM
    # server unix:/var/run/php/php7.4-fpm.sock;  # Alternative socket
}

server {
    location ~ \.php$ {
        fastcgi_pass backend;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}
  1. Timeout Issues
# Increase timeout values in nginx.conf
http {
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    fastcgi_connect_timeout 60s;
    fastcgi_send_timeout 60s;
    fastcgi_read_timeout 60s;
}

Step 3: Application Server Troubleshooting

PHP-FPM Issues

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

# Verify socket permissions
ls -la /var/run/php/php7.4-fpm.sock

# Monitor PHP-FPM processes
sudo tail -f /var/log/php7.4-fpm.log

Node.js Application Issues

# Check Node.js process
pm2 status
pm2 logs

# Restart Node.js application
pm2 restart all

# Check application logs
tail -f /var/log/node-app.log

Python/Django Issues

# Check Gunicorn status
sudo systemctl status gunicorn

# Restart Gunicorn
sudo systemctl restart gunicorn

# Check Gunicorn configuration
sudo nano /etc/systemd/system/gunicorn.service

Step 4: Load Balancer and Cloud Platform Fixes

AWS Application Load Balancer 502s

# Check target group health
aws elbv2 describe-target-health --target-group-arn arn:aws:elasticloadbalancing:...

# Verify security group rules
aws ec2 describe-security-groups --group-ids sg-12345678

# Check CloudWatch logs
aws logs filter-log-events --log-group-name /aws/applicationloadbalancer/app/my-loadbalancer

Azure Application Gateway Issues

# Check backend health via Azure CLI
az network application-gateway show-backend-health --name myAppGateway --resource-group myRG

# Verify NSG rules
az network nsg show --name myNSG --resource-group myRG

Step 5: SSL/TLS and ERR_SSL_PROTOCOL_ERROR Resolution

Certificate Issues Causing 502s

# Check SSL certificate validity
openssl x509 -in /etc/ssl/certs/domain.crt -text -noout

# Test SSL connection
openssl s_client -connect domain.com:443

# Verify certificate chain
curl -vI https://domain.com

Fix SSL Configuration in Nginx

server {
    listen 443 ssl http2;
    ssl_certificate /etc/ssl/certs/domain.crt;
    ssl_certificate_key /etc/ssl/private/domain.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    
    location / {
        proxy_pass http://backend;
        proxy_ssl_verify off;  # If backend uses self-signed cert
    }
}

Step 6: Docker and Container Issues

Docker Container 502 Debugging

# Check container status
docker ps -a
docker logs container_name

# Restart containers
docker-compose down
docker-compose up -d

# Check container networking
docker network ls
docker network inspect bridge

# Test inter-container connectivity
docker exec nginx_container ping app_container

Step 7: Performance and Resource Issues

Resource Exhaustion Causing 502s

# Check system resources
top
htop
free -h
df -h

# Check process limits
sudo -u www-data ulimit -a

# Monitor connection counts
netstat -an | grep :80 | wc -l
ss -s

Optimize Resource Settings

# Nginx worker optimization
worker_processes auto;
worker_connections 1024;
worker_rlimit_nofile 2048;

events {
    use epoll;
    multi_accept on;
}

Step 8: Monitoring and Prevention

Set Up Proactive Monitoring

# Create health check script
#!/bin/bash
STATUS=$(curl -o /dev/null -s -w "%{http_code}" http://localhost/health)
if [ $STATUS -ne 200 ]; then
    echo "Server returned $STATUS" | mail -s "Server Alert" admin@domain.com
    systemctl restart nginx
fi

# Add to crontab
*/5 * * * * /usr/local/bin/health_check.sh

Implement Circuit Breaker Pattern

# Nginx upstream with health checks
upstream backend {
    server 127.0.0.1:8001 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8002 max_fails=3 fail_timeout=30s backup;
}

Frequently Asked Questions

bash
#!/bin/bash
# Complete 502 Bad Gateway Diagnostic Script

echo "=== 502 Bad Gateway Troubleshooting ==="
echo "Timestamp: $(date)"
echo

# Check web server status
echo "1. Checking web server status..."
sudo systemctl is-active nginx apache2 2>/dev/null | head -2
echo

# Check upstream services
echo "2. Checking upstream services..."
sudo systemctl is-active php7.4-fpm php8.1-fpm mysql 2>/dev/null
echo

# Check listening ports
echo "3. Checking listening ports..."
sudo ss -tlnp | grep -E ':80|:443|:9000|:3000|:8080'
echo

# Check recent error logs
echo "4. Recent nginx errors (last 10 lines)..."
sudo tail -10 /var/log/nginx/error.log 2>/dev/null || echo "No nginx error log found"
echo

# Test local connections
echo "5. Testing local connections..."
curl -s -o /dev/null -w "HTTP %{http_code} - %{time_total}s" http://localhost/
echo
curl -s -o /dev/null -w "HTTPS %{http_code} - %{time_total}s" https://localhost/ 2>/dev/null
echo
echo

# Check system resources
echo "6. System resource usage..."
echo "Memory: $(free -h | awk '/Mem:/ {print $3"/"$2}')"
echo "Disk: $(df -h / | awk 'NR==2 {print $5" used"}')"
echo "Load: $(uptime | awk -F'load average:' '{print $2}')"
echo

# Check process counts
echo "7. Active connections..."
echo "Nginx processes: $(pgrep nginx | wc -l)"
echo "HTTP connections: $(ss -tn | grep :80 | wc -l)"
echo "HTTPS connections: $(ss -tn | grep :443 | wc -l)"
echo

# Suggested actions
echo "=== Recommended Actions ==="
echo "1. Check detailed logs: sudo tail -f /var/log/nginx/error.log"
echo "2. Restart services: sudo systemctl restart nginx php7.4-fpm"
echo "3. Test config: sudo nginx -t && sudo php-fpm7.4 -t"
echo "4. Monitor resources: htop or top"
echo "5. Check upstream health directly"
E

Error Medic Editorial

Our team of senior DevOps engineers and SRE specialists has collectively resolved thousands of production incidents across diverse infrastructure environments. We transform complex troubleshooting experiences into actionable guides that help engineers solve critical issues faster.

Sources

Related Articles in Other

Explore More browser Guides