Linux

How to Fix NGINX 502 Bad Gateway and 504 Gateway Timeout Errors

Find the real cause of NGINX 502 and 504 errors from the error log, then fix it properly.

24 October 2026  ·  5 min read  ·  Anand

How to Fix NGINX 502 Bad Gateway and 504 Gateway Timeout Errors

A 502 Bad Gateway or 504 Gateway Timeout from NGINX almost never means NGINX itself is broken. Both errors mean NGINX tried to pass the request to something behind it (PHP-FPM, a Node.js or Python app, another web server) and did not get a usable answer. The fix depends on why, and the fastest way to find out is the NGINX error log. This guide walks through the causes we see most often on production servers and how to fix each one.

502 and 504: what is the difference?

  • 502 Bad Gateway: NGINX reached the upstream but got an invalid response, or could not connect at all. The upstream is down, refusing connections, crashing mid-request or sending a response NGINX cannot use.
  • 504 Gateway Timeout: NGINX connected but the upstream took longer than the configured timeout to respond. The application is alive but too slow, or stuck.

Step 1: read the error log

Every 502 and 504 leaves a line in the NGINX error log that names the cause. Watch it while you reproduce the error:

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

The message after the timestamp tells you which section below applies:

Log message Usual cause
connect() to unix:/run/php-fpm/www.sock failed (2: No such file or directory) PHP-FPM is not running, or the socket path is wrong
connect() failed (111: Connection refused) while connecting to upstream Nothing is listening on the upstream port
(13: Permission denied) while connecting to upstream Socket permissions, or SELinux blocking the connection
upstream sent too big header while reading response header from upstream Proxy or FastCGI buffers too small
recv() failed (104: Connection reset by peer) The upstream process crashed or was killed mid-request
upstream timed out (110: Connection timed out) while reading response header from upstream Slow application or exhausted workers (the 504 case)

Step 2: is the upstream running and reachable?

For PHP sites, check PHP-FPM first. The service name differs by distribution (php-fpm on RHEL, Rocky and AlmaLinux; php8.3-fpm or similar on Debian and Ubuntu):

sudo systemctl status php-fpm
sudo ss -lxp | grep php

The socket path that ss shows must match the fastcgi_pass line in your NGINX server block exactly. For applications on a TCP port, check that something is listening and answers locally:

sudo ss -ltnp | grep 3000
curl -I http://127.0.0.1:3000/

If the local curl fails, the problem is the application, not NGINX. Check its own logs and service status.

Step 3: permissions and SELinux

A Permission denied on a Unix socket usually means the socket owner or mode does not let the NGINX user connect. In the PHP-FPM pool file, set listen.owner, listen.group and listen.mode so the nginx user can read and write the socket, then restart PHP-FPM.

On RHEL-family servers with SELinux enforcing, NGINX is also not allowed to open network connections to backends by default. If you proxy to a TCP port, check and enable the boolean:

getsebool httpd_can_network_connect
sudo setsebool -P httpd_can_network_connect 1

SELinux can also block things silently. We have seen it stop NGINX from raising its own open-files limit without logging a denial; see our case study on NGINX limits silently ignored under SELinux.

Step 4: the 504 case, slow upstreams and exhausted workers

Raising timeouts hides a 504; it rarely fixes it. First find out why the upstream is slow. For PHP-FPM, the most common reason is that every worker is busy, so new requests queue until NGINX gives up. The PHP-FPM log says so directly:

sudo grep 'max_children' /var/log/php-fpm/*.log

A message such as server reached pm.max_children setting means you need more workers (if memory allows), faster code, or caching in front of PHP. Size pm.max_children from available RAM divided by the memory a typical PHP process uses, not by guessing.

Once the cause is fixed, set timeouts that match what the application genuinely needs, for example a report generator that runs for two minutes:

location /reports/ {
    proxy_read_timeout 180s;
    proxy_pass http://app_backend;
}

For PHP the matching directive is fastcgi_read_timeout. Keep long timeouts on the specific locations that need them, not server-wide.

Step 5: buffers for large headers

Applications that set many cookies or large headers can trigger upstream sent too big header. Increase the buffers for the backend type you use:

# proxied applications
proxy_buffer_size 16k;
proxy_buffers 8 16k;

# PHP-FPM
fastcgi_buffer_size 32k;
fastcgi_buffers 16 16k;

Test and reload without dropping connections:

sudo nginx -t && sudo systemctl reload nginx

Stop it coming back

  • Alert on the rate of 5xx responses, not just on the server being up
  • Monitor PHP-FPM or application worker usage so you see exhaustion before users do
  • Cache what can be cached (FastCGI or proxy cache) so traffic spikes do not reach PHP
  • Keep NGINX configuration in version control so every change is reviewed and reversible

When to get help

If 502 or 504 errors keep returning under load, the cause is usually a capacity or architecture problem rather than a single setting. TechProvidence engineers diagnose and fix these as part of our NGINX support and performance tuning service, with 24/7 monitoring and an average response under 8 minutes. You can also contact us for a complimentary NGINX review.

Running into something similar?

We look after Linux servers, control panels and virtualization for businesses every day. If an update, vulnerability or outage here affects you, we can help.