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.

Privacy choices

We use Google Analytics to understand how visitors use this site. It never runs ads or builds advertising profiles. Visitors in the EU, UK and Switzerland aren't measured unless they opt in. Read our Privacy Statement.