Skip to content

How to Fix Nginx 502 Bad Gateway Error

DodaTech 2 min read

In this tutorial, you'll learn about How to Fix Nginx 502 Bad Gateway Error. We cover key concepts, practical examples, and best practices.

The Problem

Your site shows 502 Bad Gateway when visiting pages. Nginx acts as a reverse proxy and gets an invalid response (or no response) from the upstream server — PHP-FPM, a Node.js app, Gunicorn, or another backend. The upstream either crashed, hung, or returned an empty response.

Quick Fix

1. Check if the upstream service is running

# PHP-FPM
sudo systemctl status php8.2-fpm

# Gunicorn / uWSGI
sudo systemctl status gunicorn

# Node.js app
ps aux | grep node

# Docker backend
docker ps | grep app

2. Check Nginx error logs

sudo tail -100 /var/log/nginx/error.log

Look for specific messages:

  • connect() failed (111: Connection refused) — upstream is down
  • connect() failed (110: Connection timed out) — upstream too slow
  • upstream prematurely closed connection — upstream crashed

3. Restart the upstream service

sudo systemctl restart php8.2-fpm
sudo systemctl restart gunicorn
sudo systemctl restart nginx

4. Check the upstream socket or port

# Check if PHP-FPM socket exists
ls -la /var/run/php/php8.2-fpm.sock

# Check if the port is listening
ss -tlnp | grep 9000

Fix the socket path in Nginx config:

upstream php-backend {
    server unix:/var/run/php/php8.2-fpm.sock;
    # server 127.0.0.1:9000;
}

5. Increase proxy timeouts for slow backends

location / {
    proxy_pass http://backend:3000;
    proxy_connect_timeout 60s;
    proxy_read_timeout 60s;
    proxy_send_timeout 60s;
}

6. Clear PHP-FPM pool

# Gracefully restart the PHP-FPM process manager
sudo kill -USR2 $(cat /var/run/php/php8.2-fpm.pid)

7. Test the upstream directly

# For a Node.js/HTTP backend
curl http://127.0.0.1:3000/health

# For PHP-FPM
SCRIPT_NAME=/status SCRIPT_FILENAME=/status cgi-fcgi -bind -connect /var/run/php/php8.2-fpm.sock

Common Causes

Cause Error in Logs Fix
Backend service down connect() failed (111: Connection refused) Start or restart the upstream
Backend too slow upstream timed out (110: Connection timed out) Increase proxy timeouts
Backend crashed upstream prematurely closed connection Fix the crash, set Restart=always
PHP-FPM socket wrong connect() to unix:/var/run/php.sock failed Check socket path in config
Resource exhaustion fork() failed (12: Cannot allocate memory) Add memory or restart service
Wrong port Connection refused on port 3000 instead of 3001 Fix proxy_pass port

Test Configuration Changes First

sudo nginx -t
# nginx: the configuration file syntax is ok
# nginx: configuration file test is successful
sudo systemctl reload nginx

Always run nginx -t before reloading the configuration. This validates syntax, checks file paths, and verifies that SSL certificates are accessible before applying changes.

Prevention

  • Set up health checks on your upstream service
  • Configure proxy_next_upstream to retry failures on another server:
    proxy_next_upstream error timeout invalid_header http_502;
    
  • Use systemd Restart=always for your backend service

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro