Candid photograph of a Linux server terminal with a soft olive-green glow against a dark slate background, conveying a calm technical atmosphere.

Step-by-step guides for system administrators — covering command-line basics, web server setup, and preparation material for technical interviews.

Browse Tutorials

Troubleshooting Nginx 502 Bad Gateway Errors

An Nginx 502 Bad Gateway response means the web server accepted a client request but could not obtain a valid response from an upstream application. The upstream may be PHP-FPM, Gunicorn, uWSGI, Node.js, Apache, or a service running in a container.

The status often appears after a deployment, package update, configuration change, or sudden traffic increase. On a RHEL, CentOS, or Fedora server, a disciplined check of services, sockets, logs, permissions, and resource limits usually identifies the fault quickly.

Identify Which Upstream Is Failing

Start by confirming whether Nginx serves static files correctly. Create or locate a small file in the configured document root, then request it with curl:

curl -I http://127.0.0.1/health.html

A successful static response suggests that Nginx itself is running and the problem is between Nginx and the application server. If static content also fails, check the Nginx service and configuration before investigating PHP-FPM or another backend.

Inspect the active virtual host configuration to find the upstream definition:

sudo nginx -T

Look for proxy_pass, fastcgi_pass, uwsgi_pass, or upstream directives. The address may be a TCP port such as 127.0.0.1:8000 or a Unix socket such as /run/php-fpm/www.sock.

Check Application Service Health

A backend process that has stopped, crashed, or failed during startup is one of the most common causes of a 502 response. Check the relevant unit and recent journal entries:

sudo systemctl status php-fpm
sudo journalctl -u php-fpm --since "30 minutes ago"

For a Python or Node.js application, replace php-fpm with the appropriate systemd unit. systemctl is-enabled can also reveal whether the service will return after a reboot.

On a Fedora or RHEL host, SELinux may prevent a service from accessing files or binding to a port even when the unit appears active. Review recent denials with:

sudo ausearch -m AVC -ts recent

Do not disable SELinux as a first response. Correct file contexts, booleans, or policy rules after confirming the denial is related to the failed request.

Verify Ports, Sockets, and Permissions

Test the upstream directly from the server. For a TCP application, use:

curl -v http://127.0.0.1:8000/
sudo ss -ltnp | grep ':8000'

A connection refusal usually means no process is listening, while a timeout can indicate a hung application, firewall rule, or overloaded host. A local socket requires a different check:

sudo ls -l /run/php-fpm/www.sock
sudo ss -lx | grep php

Nginx must have permission to connect to the socket. Check the Nginx worker account with ps -ef | grep nginx, then compare it with the socket owner and group. On some installations, adding the account to the correct group and restarting PHP-FPM resolves the error.

Use Logs to Separate Symptoms

Nginx’s error log often states the exact failure class. Review entries around the time of a test request:

sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

The message connect() failed (111: Connection refused) points to an unavailable listener. upstream timed out indicates that the application did not respond within the configured interval. Permission denied commonly indicates a Unix socket, SELinux, or filesystem access problem.

Nginx log message Likely cause Useful check
Connection refused Backend stopped or wrong port systemctl status, ss -ltnp
Upstream timed out Slow, stuck, or overloaded application journalctl, CPU and memory usage
Permission denied Socket ownership or SELinux policy ls -l, ausearch
No live upstreams All defined backends unavailable nginx -T, backend health
Prematurely closed connection Application crash or protocol issue Application log and restart history

After each change, repeat the same request rather than relying on a browser refresh. A reproducible curl command makes it easier to compare results before and after a fix.

Review Proxy and FastCGI Settings

A valid backend can still produce gateway errors when Nginx passes the wrong protocol, path, or headers. Confirm that proxy_pass points to the service’s actual listening address and that a FastCGI configuration includes the expected script parameters:

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php-fpm/www.sock;
}

For reverse proxy applications, verify forwarding headers and URI behaviour. An extra path component in proxy_pass can change the request sent upstream, producing application-level failures that look like a gateway problem.

Use a syntax test before reloading:

sudo nginx -t
sudo systemctl reload nginx

Increase proxy_read_timeout or fastcgi_read_timeout only when logs show a legitimate long-running request. A larger timeout will not repair a stopped backend and can leave workers occupied for longer.

Check Capacity and Network Controls

A burst of requests can exhaust PHP-FPM workers, file descriptors, memory, or connection tracking entries. Check the host while reproducing the error:

free -h
uptime
top
sudo journalctl -k --since "1 hour ago" | grep -i -E 'oom|killed'

An out-of-memory kill, full filesystem, or saturated worker pool can cause intermittent 502 responses. Review PHP-FPM’s pm.max_children, application worker counts, and database connection limits together rather than increasing one value blindly.

For services hosted across machines, check firewalld, cloud security groups, routing, and DNS. An application moved from an Australian Sydney region to Melbourne, for example, may expose a changed private address or port while Nginx still uses the old endpoint. Local tests from the proxy host are more useful than a browser test from Brisbane or Perth.

Prevent Repeat Gateway Failures

Record the working upstream address, service name, socket permissions, and reload procedure in the server runbook. Monitor both the public endpoint and the backend directly, because a simple HTTP check can show that Nginx is alive while the application is failing.

Schedule maintenance outside the busiest periods for the site’s users, allowing for Australian Eastern, Central, and Western time zones. An NBN connection, a cloud instance in Sydney, or a business platform serving Melbourne customers may have very different peak periods from a global dashboard.

Keep RHEL and Fedora packages current, but stage updates and verify services afterwards. For automated patching, the DNF automatic guide explains how to control update timing and reboot decisions. This is particularly important where the Privacy Act 1988, customer records, or Essential Eight-aligned operational practices require predictable maintenance and audit evidence.

Build a Practical Recovery Checklist

A concise recovery sequence reduces guesswork: test a static file, inspect nginx -T, check the backend unit, test the upstream directly, read both logs, verify permissions, and reload only after nginx -t succeeds. Save the relevant output with the incident time so recurring faults can be compared.

The Linuxtpoint tutorials provide related Linux administration material for service management, firewalls, and package maintenance. Keep credentials and personal data out of diagnostic archives, especially when logs are copied into ticketing systems or shared between teams.

For the next incident, run sudo nginx -T, sudo systemctl status <backend-service>, and curl -v http://<upstream-address> in that order.