Meet us at CloudFest Americas Nov 10–12 · Miami

Book a meeting
Runbook · WordPress & Web

Fix 502 Bad Gateway on Nginx with PHP-FPM

Diagnose and fix Nginx 502 Bad Gateway errors caused by PHP-FPM being down, socket path mismatches, permissions, SELinux, or exhausted pm.max_children.

Applies to
  • Nginx
  • PHP-FPM
  • AlmaLinux
  • Rocky Linux
  • RHEL
  • Ubuntu
  • Debian
Skill level
Intermediate
Last reviewed

Quick fix: A 502 means Nginx couldn't get a valid response from PHP-FPM. Read the Nginx error log (tail -50 /var/log/nginx/error.log). The message tells you which of these it is: PHP-FPM isn't running, Nginx is pointing to the wrong socket, a permissions problem, or PHP-FPM has run out of worker processes.

Step 1: Read the Nginx error log

tail -50 /var/log/nginx/error.log

Match what you see to the causes below:

Log message containsLikely causeGo to
(2: No such file or directory) on a .sockPHP-FPM is down, or the socket path is wrongSteps 2 and 3
(111: Connection refused)PHP-FPM is down, or listening on a different portSteps 2 and 3
(13: Permission denied)Socket permissions or SELinuxStep 4
upstream prematurely closed connectionPHP worker crashed or hit a limitStep 5
upstream timed out (110A slow script. Usually returns a 504, not a 502Step 6

Step 2: Is PHP-FPM running?

# AlmaLinux / Rocky / RHEL
systemctl status php-fpm

# Ubuntu / Debian (the version number varies)
systemctl status php8.3-fpm

If it's stopped, check its configuration before starting it, since a syntax error is a common reason it won't start:

php-fpm -t          # RHEL family
php-fpm8.3 -t       # Ubuntu / Debian

systemctl start php-fpm

Step 3: Do Nginx and PHP-FPM agree on the socket?

Find where Nginx sends PHP requests:

grep -R "fastcgi_pass" /etc/nginx/

Find where PHP-FPM is listening:

# AlmaLinux / Rocky / RHEL
grep -R "^listen" /etc/php-fpm.d/

# Ubuntu / Debian
grep -R "^listen" /etc/php/*/fpm/pool.d/

The two must match exactly, for example unix:/run/php-fpm/www.sock in Nginx and listen = /run/php-fpm/www.sock in PHP-FPM. Mismatches are especially common after a PHP version upgrade on Ubuntu, because the socket name includes the version number (php8.1-fpm.sock becoming php8.3-fpm.sock).

Step 4: Fix permission errors

The PHP-FPM pool must let the Nginx user connect to its socket. In the pool configuration, check:

listen.owner = nginx      ; "www-data" on Ubuntu / Debian
listen.group = nginx
listen.mode = 0660

On AlmaLinux, Rocky and RHEL, SELinux can also block the connection even when file permissions are correct. Check for recent denials:

ausearch -m avc -ts recent | grep -i -E "nginx|php"

Don't disable SELinux to make the error go away. If it's blocking a legitimate connection, fix the file context or the relevant boolean so the server keeps its protection.

Step 5: Has PHP-FPM run out of workers?

Under load, PHP-FPM may hit its worker limit and stop accepting requests. Check its log:

grep -i "max_children" /var/log/php-fpm/error.log     # RHEL family
grep -i "max_children" /var/log/php8.3-fpm.log        # Ubuntu / Debian

A message like server reached pm.max_children setting confirms it. Before raising the limit, work out how many workers the server's RAM can actually support. Find the average memory per worker:

ps --no-headers -o rss -C php-fpm | awk '{s+=$1; n++} END {printf "%.0f MB average per worker\n", s/n/1024}'

(On Ubuntu, replace php-fpm with php-fpm8.3.) Divide the RAM you can spare for PHP by that number to get a safe pm.max_children. Setting it higher than memory allows causes swapping and out-of-memory kills, which is worse than the 502.

Step 6: Timeouts (504 Gateway Timeout)

If the log shows upstream timed out, PHP is responding, just too slowly. Find the slow script rather than raising timeouts indefinitely. PHP-FPM's slow log (slowlog and request_slowlog_timeout in the pool config) shows exactly which code is slow.

Apply and verify

nginx -t && systemctl reload nginx
systemctl restart php-fpm
curl -sI https://your-site.example | head -1

You should see HTTP/2 200 (or HTTP/1.1 200 OK). Keep watching /var/log/nginx/error.log for a while to make sure the errors have stopped.

Prevent it from happening again

  • Monitor site availability from outside the server, so a 502 alerts someone within minutes.
  • Size PHP-FPM workers to the server's memory, and review them when traffic grows.
  • After any PHP upgrade, check that every Nginx fastcgi_pass points to the new socket.

Want a second pair of eyes on your configuration? Our performance review covers PHP-FPM sizing, caching and web server tuning.