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 contains | Likely cause | Go to |
|---|---|---|
(2: No such file or directory) on a .sock | PHP-FPM is down, or the socket path is wrong | Steps 2 and 3 |
(111: Connection refused) | PHP-FPM is down, or listening on a different port | Steps 2 and 3 |
(13: Permission denied) | Socket permissions or SELinux | Step 4 |
upstream prematurely closed connection | PHP worker crashed or hit a limit | Step 5 |
upstream timed out (110 | A slow script. Usually returns a 504, not a 502 | Step 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_passpoints 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.