A 502 Bad Gateway error from Nginx usually means Nginx itself is running, but something went wrong when it tried to communicate with the service responsible for generating the response.
For a typical PHP website, that service is PHP-FPM.
The request normally looks something like this:
Browser
|
v
Nginx
|
v
PHP-FPM
|
v
Application
If PHP-FPM is unavailable, Nginx is pointing at the wrong socket, permissions prevent access, or PHP takes too long to respond, Nginx may return a 502.
Rather than restarting services or changing configuration at random, work through the problem in order. In many cases, the Nginx error log will tell you exactly where to start.
Start by checking the error log.
On many Ubuntu and Debian servers:
sudo tail -n 100 /var/log/nginx/error.log
To watch the log while reproducing the error:
sudo tail -f /var/log/nginx/error.log
Common messages include:
connect() to unix:/run/php/php8.4-fpm.sock failed
connect() failed (111: Connection refused) while connecting to upstream
connect() to unix:/run/php/php8.4-fpm.sock failed (13: Permission denied)
upstream timed out while reading response header from upstream
Each points towards a different problem.
If your website uses a custom error log, you can inspect the active Nginx configuration with:
sudo nginx -T
Look for the error_log directive for the affected site.
One of the simplest causes of a 502 is PHP-FPM not running.
On Ubuntu or Debian, check the service for the PHP version used by the website:
sudo systemctl status php8.4-fpm
If you are unsure which PHP-FPM services are installed:
systemctl list-units --type=service | grep php
Check recent PHP-FPM logs:
sudo journalctl -u php8.4-fpm -n 100
If PHP-FPM has stopped, you can try starting it:
sudo systemctl start php8.4-fpm
If it immediately fails again, do not keep restarting it. The service logs should tell you why.
Common causes include configuration errors, broken extensions, missing files or directories, and resource problems.
Nginx and PHP-FPM need to agree on how they communicate.
A common configuration uses a Unix socket:
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
Check what Nginx is configured to use:
sudo nginx -T | grep fastcgi_pass
Then check which PHP sockets actually exist:
ls -la /run/php/
A common problem after changing PHP versions is finding Nginx configured for:
/run/php/php8.3-fpm.sock
while PHP-FPM now provides:
/run/php/php8.4-fpm.sock
You should also check PHP-FPM itself.
On Ubuntu and Debian:
grep '^listen =' /etc/php/8.4/fpm/pool.d/*.conf
You may see:
listen = /run/php/php8.4-fpm.sock
Nginx and PHP-FPM must point to the same location.
Some configurations use TCP instead:
listen = 127.0.0.1:9000
with Nginx configured as:
fastcgi_pass 127.0.0.1:9000;
If you are using TCP, check whether something is actually listening on the configured port:
sudo ss -ltnp | grep ':9000'
If nothing is listening, increasing Nginx timeouts will not solve the problem.
If the Nginx error log contains:
Permission denied
and references the PHP-FPM socket, Nginx can find the socket but cannot access it.
Check its ownership and permissions:
ls -l /run/php/
You might see:
srw-rw---- 1 www-data www-data php8.4-fpm.sock
Now check which user the Nginx worker processes use:
ps -eo user,group,pid,cmd | grep '[n]ginx'
PHP-FPM controls its socket permissions through its pool configuration:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
The Nginx worker needs permission to connect to the socket.
Do not fix this with:
chmod 777 /run/php/php8.4-fpm.sock
Apart from granting unnecessary access, PHP-FPM normally recreates the socket when it restarts, so the change may disappear.
Correct the PHP-FPM pool configuration instead, then restart PHP-FPM:
sudo systemctl restart php8.4-fpm
If the ownership and permissions look correct but access is still denied on a RHEL-family system, remember that SELinux may also be involved.
PHP-FPM can be running normally but still be unable to handle requests quickly enough.
PHP-FPM uses worker processes to execute PHP requests. One important pool setting is:
pm.max_children = 10
This limits how many requests the pool can process simultaneously.
Check for messages indicating that the limit has been reached:
sudo journalctl -u php8.4-fpm | grep -i max_children
You may find something similar to:
server reached pm.max_children setting
You can also inspect the PHP-FPM processes:
ps -eo pid,user,%cpu,%mem,etime,cmd | grep '[p]hp-fpm'
Reaching pm.max_children does not automatically mean the value should be increased.
Workers may be busy because of:
Increasing the number of workers also increases PHP-FPM's potential memory usage.
Check available memory before changing it:
free -h
If requests are unexpectedly slow, PHP-FPM's slow log can help identify what workers are doing.
A pool can be configured with:
request_slowlog_timeout = 5s
slowlog = /var/log/php8.4-fpm-slow.log
This can be far more useful than simply increasing pm.max_children and hoping the problem goes away.
Another common error is:
upstream timed out while reading response header from upstream
This is different from Nginx being unable to connect to PHP-FPM.
Nginx connected successfully, but PHP-FPM did not return a response quickly enough.
The relevant Nginx configuration may include:
fastcgi_read_timeout 60s;
Increasing that timeout can be appropriate for a request that genuinely needs more time, but it should not be the first response to an unexpectedly slow application.
Check:
For a Laravel application, for example, the application log is normally:
storage/logs/laravel.log
You can watch it while reproducing the problem:
tail -f storage/logs/laravel.log
If a web request routinely needs several minutes to complete, it may be better handled by a background queue rather than by increasing HTTP timeouts.
Sometimes PHP-FPM is the victim rather than the cause.
Check available memory:
free -h
Check disk usage:
df -h
Check inode usage:
df -i
A full filesystem can prevent PHP applications from writing sessions, caches, temporary files and logs.
Low memory can also cause the Linux kernel to terminate PHP-FPM or other services.
Check for out-of-memory events:
journalctl -k | grep -i -E 'out of memory|oom|killed process'
If PHP-FPM keeps disappearing unexpectedly, an OOM kill is worth checking before spending time changing PHP configuration.
Once you have found the problem, test configuration changes before applying them.
For Nginx:
sudo nginx -t
A successful result should include:
syntax is ok
test is successful
You can then reload Nginx:
sudo systemctl reload nginx
If you changed PHP-FPM configuration, test that too. On an Ubuntu server running PHP 8.4:
sudo php-fpm8.4 -t
Then restart or reload PHP-FPM as required.
Testing first prevents a typo made during troubleshooting from turning a partial outage into a complete one.
If you need the short version, work through these checks:
Read the Nginx error log
sudo tail -n 100 /var/log/nginx/error.log
Check PHP-FPM
sudo systemctl status php8.4-fpm
sudo journalctl -u php8.4-fpm -n 100
Compare Nginx's upstream with PHP-FPM
sudo nginx -T | grep fastcgi_pass
ls -la /run/php/
If you see Permission denied, check the socket ownership and Nginx worker user
ls -l /run/php/
ps -eo user,group,pid,cmd | grep '[n]ginx'
If PHP-FPM is running but requests are slow, check workers, memory and application logs
free -h
ps -eo pid,user,%cpu,%mem,etime,cmd | grep '[p]hp-fpm'
Check for server-level problems
df -h
journalctl -k | grep -i -E 'out of memory|oom|killed process'
The error in the Nginx log should determine which path you follow rather than changing several settings at once.
When you manage several servers, troubleshooting becomes easier if you can quickly get to the relevant server, website and logs.
ServerAuth provides central access to your servers and server logs, helping you investigate issues such as a 502 without first hunting down the correct server details and log locations.
The underlying process remains the same: find out whether Nginx can reach PHP-FPM, whether PHP-FPM is healthy, and whether the application is responding normally.
A 502 Bad Gateway page is usually a symptom rather than the underlying problem.
For a PHP website behind Nginx, start with the Nginx error log. It will often tell you whether PHP-FPM is unavailable, the socket is wrong, permissions are blocking the connection, or the upstream is simply taking too long to respond.
From there, work through the specific problem rather than restarting everything or increasing limits at random.
That approach will solve most Nginx and PHP-FPM 502 errors while also giving you a much better idea of what actually went wrong.
ServerAuth provides a whole host of management tools, from controlling who can access your server, to managing your website deployments. And with an ever-growing suite of tools you'll always be one step ahead!
Start for free