Fixing Nginx 502 Bad Gateway Errors: Step-by-Step Guide
Trace Nginx 502 errors by checking config, upstream health, logs, sockets, Docker networking, and timeout symptoms.
Fixing Nginx 502 Bad Gateway Errors: Step-by-Step Guide
Fixing Nginx 502 Bad Gateway errors starts with understanding that Nginx is usually the messenger, not the original source of the failure. A 502 means Nginx tried to talk to an upstream service and got no valid response.
That upstream service might be a Node.js app, PHP-FPM, Gunicorn, Puma, a container, or another HTTP server. Your job is to find where the handoff fails.
What a 502 Bad Gateway Means in Nginx
Nginx commonly sits in front of an application server. It accepts public traffic, handles TLS, serves static files, and forwards dynamic requests upstream.
A 502 appears when that upstream connection fails or returns something Nginx cannot use. Common causes include:
- The application process is stopped.
- Nginx points to the wrong port or socket.
- A Unix socket has the wrong permissions.
- The upstream service crashes during the request.
- A firewall or container network blocks the connection.
- The upstream sends an invalid HTTP response.
Start with the exact request path that fails. If only /api returns 502 but static pages load, your static file serving is fine and the proxy or app backend is the likely problem. If every page fails, the issue may be a broader Nginx, DNS, or upstream availability problem.
Step 1: Check Nginx Status and Configuration
First confirm Nginx is running:
systemctl status nginx
Then test the configuration:
nginx -t
If the config test fails, fix that before chasing the application. Nginx may still be running with an older config, or it may fail on reload.
After a successful config test, reload Nginx:
systemctl reload nginx
Do not restart blindly on a busy server unless you understand the impact. Reloading is usually enough after a config change and is less disruptive.
Next, inspect the active server block. Look for proxy_pass, fastcgi_pass, or uwsgi_pass. A typical reverse proxy might include:
location / {
proxy_pass http://127.0.0.1:3000;
}
That means Nginx expects an application on local port 3000. If the app actually listens on 3001, or only inside a Docker network, Nginx will fail.
For more command-focused checks, see Nginx configuration testing commands.
Step 2: Verify the Upstream Service
Now test the upstream directly from the Nginx host. If Nginx proxies to 127.0.0.1:3000, run:
curl -i http://127.0.0.1:3000/
If that fails, the problem is not the browser or public DNS. Nginx cannot reach the backend because the backend is down, listening somewhere else, or rejecting the request.
Check the application process:
ss -ltnp
Look for the expected port. If the service uses a Unix socket, check the socket path:
ls -l /run/app/app.sock
The Nginx worker user must be able to access that socket. On many Linux systems, Nginx runs as www-data, nginx, or a service-specific user. If the socket is owned by a different user and not group-readable or writable as needed, Nginx may log a permission error and return 502.
For a PHP-FPM setup, confirm the pool is running:
systemctl status php-fpm
The service name may include a version, such as php8.2-fpm, depending on the distribution.
Step 3: Read the Nginx Error Log
The Nginx error log usually tells you which failure mode you are dealing with. Common log messages include:
connect() failed (111: Connection refused) while connecting to upstream
This means Nginx reached the host but nothing accepted the connection on that port.
upstream timed out while reading response header from upstream
This means Nginx connected, but the backend did not respond in time.
permission denied while connecting to upstream
This often points to Unix socket permissions or security controls such as SELinux.
Check recent errors with:
tail -n 100 /var/log/nginx/error.log
On systemd-based systems, you can also check:
journalctl -u nginx -n 100
Match the timestamp in the log with the time of your browser request. This keeps you from chasing old errors that are no longer relevant.
For a deeper log workflow, see analyzing Nginx error logs.
Step 4: Fix the Most Common Root Causes
Once you know the failure mode, apply the smallest fix that matches it.
If the app is not running, start or restart the application service:
systemctl restart your-app
Then test the upstream with curl before testing through Nginx.
If Nginx points to the wrong port, update the proxy_pass target and reload Nginx. Make sure your app and Nginx agree on IPv4 versus IPv6 too. An app listening on 127.0.0.1 is not the same as one listening only on ::1.
If Docker is involved, check whether Nginx runs on the host or inside a container. 127.0.0.1 inside a container points to that container, not the host. You may need a Docker service name, bridge network, or published port.
If the upstream times out, check application logs. The backend may be stuck on database queries, external API calls, or startup work. Raising Nginx timeouts can hide symptoms, but it will not fix a broken or overloaded app.
When to Call a Professional
Bring in a senior engineer or hosting provider when 502 errors affect production and the cause is not obvious after checking logs, upstream status, and recent deploys. Also get help if the issue touches load balancers, container orchestration, SELinux policy, or high-traffic timeout tuning.
For production systems, avoid repeated random restarts. They can clear evidence and make the outage harder to understand.
A 502 Bad Gateway error is fixable when you trace the request path in order. Confirm Nginx is valid, test the upstream directly, read the exact error log line, and apply the fix that matches the failure. That approach is faster and safer than changing timeouts or restarting services blindly.