How to Fix Nginx 502 Bad Gateway in 5 Minutes

A 502 Bad Gateway error means Nginx successfully received a request from the client but got an invalid response from the upstream server it was proxying to. In plain terms: Nginx is working fine, but the backend service it forwards requests to is either down, misconfigured, or crashing.

This is one of the most common production errors. It is rarely a Nginx bug itself. The upstream — PHP-FPM, Node.js, Python Gunicorn, or any other app server — is the source. Follow these five steps to identify and fix the root cause in under five minutes.

Step 1: Check if the Upstream Process Is Running

The most common cause of a 502 is that the upstream service simply stopped. Before anything else, confirm it is running:

# For PHP-FPM
systemctl status php-fpm

# For Node.js (via PM2)
pm2 status

# For Python / Gunicorn
systemctl status gunicorn

# For Ruby / Puma (systemd)
systemctl status puma

Look for the Active: active (running) line. If the service shows inactive or failed, restart it and check if the 502 clears:

# Restart the upstream service
systemctl restart php-fpm

# Or with PM2
pm2 restart all

If the service restarts but immediately crashes again, check the service-specific log (Step 3 below) for the real error.

Advertisement

Step 2: Verify the Upstream Configuration in nginx.conf

If the upstream is running, the next most likely cause is a mismatch between what Nginx expects and where the upstream is actually listening. Open your Nginx configuration and find the proxy_pass or upstream block:

# Inside your server block or upstream block
upstream php_backend {
    server unix:/run/php/php-fpm.sock;
    # or
    server 127.0.0.1:9000;
}

server {
    location ~ \.php$ {
        fastcgi_pass php_backend;
        # ...
    }
}

Common mistakes to look for:

After any change, test and reload Nginx:

nginx -t          # Test configuration syntax
nginx -s reload   # Reload without dropping connections

Step 3: Check Nginx and Upstream Logs

The error logs will almost always tell you exactly what went wrong. Check both Nginx and the upstream service:

# Nginx error log (most useful for 502s)
tail -50 /var/log/nginx/error.log

# PHP-FPM error log
tail -50 /var/log/php-fpm/error.log
# or, depending on your pool config:
tail -50 /var/log/php8.2-fpm/error.log

# Node.js app log
pm2 logs --lines 50

# Gunicorn log
journalctl -u gunicorn --no-pager -n 50

Key error messages to watch for:

Step 4: Apply Common Fixes

Based on the log output, apply the appropriate fix from the table below:

4a. Restart the Upstream Service

systemctl restart php-fpm

If the service keeps crashing, investigate the upstream error log. Common culprits: out-of-memory (OOM killer), corrupted PHP files, or a broken dependency update.

4b. Fix Socket Permissions

If the error log shows Permission denied on the socket file, Nginx (usually running as nginx or www-data) cannot access it:

# Check the socket file owner and permissions
ls -la /run/php/php-fpm.sock

# The PHP-FPM pool config controls this:
# /etc/php/8.2/fpm/pool.d/www.conf
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

After updating the pool config, restart PHP-FPM:

systemctl restart php-fpm

4c. Increase Proxy Buffer Sizes

Sometimes the upstream sends headers or body content that exceed Nginx's default buffer limits, causing a 502. Add these directives inside your location, server, or http block:

proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_read_timeout 300;

Then reload Nginx:

nginx -s reload

4d. Increase Upstream Timeout Settings

If slow upstream responses cause the 502, adjust the timeout values:

fastcgi_read_timeout 300;
fastcgi_send_timeout 300;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;

Step 5: Verify the Fix

After applying any fix, verify that the 502 is resolved:

# Quick local test
curl -I http://localhost

# Expected response:
# HTTP/1.1 200 OK
# Content-Type: text/html; charset=UTF-8
# ...

# Test from external (replace with your domain)
curl -I https://example.com

You should see a 200 OK (or 301/302 redirect), not a 502 Bad Gateway. Also load the site in a browser to confirm end-to-end functionality.

Quick Reference: Causes and Fixes

Symptom / Log Message Root Cause Fix
Connection refused Upstream not running or wrong port Start upstream; verify port/socket in config
Permission denied on socket Nginx user cannot read socket file Set listen.owner and listen.mode in pool config
upstream prematurely closed connection Upstream crashed (OOM, fatal error) Check upstream log; increase memory limit
502 only on large pages Proxy buffer too small Increase proxy_buffer_size and proxy_buffers
502 on slow requests Timeout exceeded Increase fastcgi_read_timeout or proxy_read_timeout
502 after server reboot Upstream service not enabled at boot systemctl enable php-fpm
Pro tip: If you are running behind Cloudflare or another CDN and see a 502 in the browser but not in curl from the server, the 502 may originate from the CDN layer. Check your CDN dashboard for origin connection errors.

Related Guides