Longer note: How a Laravel request travels.
// problem · 2 april 2026 · 1 min
Nginx/PHP-FPM 502 that looked like Laravel
The application log was empty because PHP never ran.
Time wasted: 90 minutes
Problem
Production returned 502 or a blank page. Staging was healthy. Laravel’s log file did not grow.
Environment
Ubuntu
Nginx
PHP-FPM
Laravel
Symptoms
Intermittent 502 Bad Gateway. No storage/logs lines for the failing requests. Restarting php-fpm “fixed” it until the pool filled again.
Expected
A Laravel response, or at least an exception in storage/logs.
Investigation
Read Nginx and FPM error logs. Checked the unix socket path and ownership. Looked at pm.max_children.
Things I tried
Deployed again. Blamed OPcache. Increased workers without measuring. Added Log::info at the top of index.php - which never ran.
Root cause
Nginx could not get a valid response from PHP-FPM: socket permissions and/or a saturated pool. The framework was innocent.
Solution
Fixed socket ownership so the Nginx user could connect. Confirmed pool exhaustion before raising workers.
Why it worked
HTTP 502 is Nginx talking about upstream, not Laravel talking about your controller.
Lesson
If index.php never runs, your framework cannot confess. Debug the boundary between Nginx and FPM.
Found something wrong?
These notes can be incomplete, or wrong in a different environment. Suggest a correction on GitHub or email me at me@t4mer.net.
// related
// article
How a Laravel request actually travels through Nginx → PHP-FPM → Laravel
502s, blank pages, and the temptation to add logging in the wrong process.
// til
TIL: what PHP-FPM actually does
PHP-FPM is a pool of PHP processes. Nginx does not speak PHP. It speaks FastCGI to that pool.
// problem
Different PHP versions between CLI and the web server
The command line told the truth about a different binary than PHP-FPM.