502 Bad Gateway: which layer of your stack actually failed
TL;DR: A 502 means one server acting as a gateway asked another server for a response and did not get a valid one. It is never a single condition, because a modern stack has several gateway relationships: CDN to origin, reverse proxy to web server, web server to PHP-FPM.
The diagnostic question is therefore not "what causes 502" but "which gap failed." Bypass the CDN and the answer halves immediately. Then check whether PHP-FPM is running and whether it has free workers, because on a WordPress site the web-server-to-PHP-FPM gap accounts for most of them, and the two usual causes are an exhausted worker pool or a script exceeding its timeout.
What a 502 actually says
HTTP 502 Bad Gateway is returned by a server that was acting as a gateway or proxy, when the upstream server it contacted returned something invalid or nothing at all.
The key word is upstream. A 502 is always about a relationship between two components, and the component returning the error is not the one that failed. Nginx returning 502 means nginx is working fine; whatever nginx asked did not answer.
That is why "how do I fix a 502" has no single answer, and why generic advice to clear your browser cache is close to useless. The browser is not involved in the failure.
Distinguish it from its neighbours:
500 means the server processing the request hit a fault itself. 502 means it could not get a usable answer from something behind it. 503 means the server is up but deliberately declining, usually resource limits or maintenance. 504 means the upstream was contacted but took too long to respond, which overlaps heavily with 502 in practice since some proxies return 502 where others return 504.
For a WordPress site, the practical translation of 502 is nearly always: PHP is not answering. Either the process manager is down, it has no free workers, or the script died or timed out mid-request.
The gateway relationships in a typical stack
Modern hosting has several, and a 502 could come from any of them.
Browser to CDN. If you use Cloudflare or a similar service, it sits in front and proxies to your origin. If the origin does not answer, the CDN returns an error, and Cloudflare's own error pages are usually distinguishable from an nginx one.
CDN to origin server. The most common failure here is the origin being unreachable, overloaded, or refusing the connection.
Reverse proxy to web server. Some setups run a caching proxy in front of the application server.
Web server to PHP-FPM. Nginx does not execute PHP; it passes requests to PHP-FPM over a socket or TCP connection and returns whatever comes back. If PHP-FPM does not answer, nginx returns 502. This is the gap that produces most WordPress 502s.
Application to database. A database failure usually produces a different error, but a PHP process hanging on a database connection can exhaust workers and produce 502 indirectly.
The diagnostic value of this list: each relationship can be tested independently, and testing them in order eliminates most of the space quickly.
Apache with mod_php behaves differently, since PHP runs inside the web server process rather than as a separate service. Apache setups tend to produce 500 errors where an nginx and PHP-FPM stack produces 502, which is why the same underlying fault presents differently depending on your stack.
Step one: is it the CDN or the origin?
If you use a CDN or proxy, resolve this first, because it halves the problem in one step.
Read the error page. Cloudflare returns branded error pages with specific codes. Error 502 from Cloudflare with their styling means the origin did not respond acceptably. A plain nginx 502 page means the error came from your server.
Bypass the CDN. Edit your local hosts file to map your domain directly to the origin server's IP, then load the site. Only your machine bypasses the proxy.
If the site works when bypassing, the fault is in the CDN-to-origin relationship: origin firewall blocking the CDN's addresses, an SSL configuration mismatch between CDN and origin, or the origin being reachable from you but not from the CDN's network.
If the site fails when bypassing too, the origin is the problem and you can ignore the CDN entirely.
Check the CDN's own status. Occasionally the fault is theirs.
Check origin firewall rules. A common cause after enabling a CDN, or after a security plugin adds rules, is the origin blocking the proxy's IP ranges. The symptom is a 502 for everyone while the origin works fine when accessed directly.
Check SSL between CDN and origin. If the CDN is configured for full SSL verification and the origin certificate is expired, self-signed or mismatched, the connection fails and you get a 502. This appears after a certificate change and is easy to miss.
Step two: is PHP-FPM running?
Assuming the origin is at fault, this is the next check and it takes seconds.
On a VPS, check the service status. If it is not running, start it and read the log to find out why it stopped. If it starts and immediately dies, the log names the reason, usually a configuration syntax error or a resource problem.
On shared hosting, you have no direct visibility. What you can do is check whether other sites on the account are affected, which distinguishes a server-level problem from a site-level one, and then contact support with that information.
Check the socket or port. Nginx connects to PHP-FPM over a Unix socket or a TCP port defined in both configurations. If they disagree, every request 502s. This happens after upgrading PHP, since the socket path often includes the version number and the nginx configuration still points at the old one.
That specific failure — upgrade PHP, socket path changes, nginx unchanged — is one of the most common causes of a sudden total 502 on a VPS, and it is entirely invisible unless you know to look for it.
Read both logs. The nginx error log tells you what nginx tried and what happened, typically "connect() to unix:/run/php/php8.x-fpm.sock failed" or "upstream prematurely closed connection". The PHP-FPM log tells you what PHP was doing. Together they usually name the cause.
Cause: worker pool exhausted
The most common cause of intermittent 502s on a busy site.
PHP-FPM runs a fixed pool of worker processes. Each handles one request at a time. When all workers are busy, new requests queue, and when the queue fills, nginx gets no answer and returns 502.
The signal: 502s appear under load and clear when traffic drops. The site works fine at 3am and fails at peak. The PHP-FPM log may show messages about the process pool being exhausted and suggesting an increase in pm.max_children.
Why workers get consumed:
Uncached requests, which is the underlying issue on most WordPress sites. A cached page never reaches PHP; an uncached one occupies a worker for its full duration. If caching is broken or not configured, every visitor consumes a worker.
Slow requests holding workers longer than necessary. A checkout taking four seconds occupies a worker for four seconds, so a slow page reduces your effective concurrency dramatically.
Requests waiting on something external: a slow database query, a third-party API call with no timeout, or a remote request that hangs.
Bot traffic hitting uncacheable URLs such as search results, which is a surprisingly common cause.
The fixes, in order of value:
Get full-page caching working and verify it with response headers rather than assuming. This removes most PHP requests outright and is far more effective than tuning worker counts.
Fix slow queries and slow pages, since faster requests free workers sooner.
Add timeouts to any external API call, because a hanging remote request can occupy a worker indefinitely.
Block abusive bot traffic.
Then, and only then, raise pm.max_children. Raising it without addressing load simply moves the failure point, and setting it too high causes memory exhaustion, which turns a queueing problem into a crashing one. The practical ceiling is your available RAM divided by average per-process memory usage.
Cause: script timeout
A PHP script ran longer than a configured limit and was terminated mid-response, so nginx received an incomplete answer.
Multiple timeouts are involved, and they must be consistent with each other:
PHP's max_execution_time. PHP-FPM's request_terminate_timeout. Nginx's fastcgi_read_timeout. And if a CDN is in front, its own timeout, which on some providers is fixed and cannot be raised.
If nginx's timeout is shorter than PHP's, nginx gives up while PHP is still working, and you get a 502 even though the script would have completed.
When this happens: large imports and exports, backup jobs run through the browser, bulk operations in the admin area, image processing on very large uploads, a migration plugin, or a plugin making a slow external API call.
The right fix depends on the operation. For a genuinely long task like an import, raising the timeouts for that operation is legitimate. For a normal page load timing out, raising limits hides a real performance problem that will get worse.
Better than raising timeouts: move long operations out of the request cycle. Run imports and backups via WP-CLI or a proper background queue rather than through the browser, where they are subject to every timeout in the chain and will fail again at a larger data volume.
If a CDN is in front, note that its timeout may be lower than everything else and may not be adjustable, which means a long-running admin operation can 502 at the CDN regardless of your server configuration. Bypass the CDN for those operations.
Cause: PHP-FPM crashed or restarting
If PHP-FPM is dying, requests during the gap get 502s.
Out of memory is the leading cause on small servers. PHP-FPM workers each consume memory, and pm.max_children set too high means a traffic spike exhausts RAM and the OOM killer terminates processes. This is why raising the worker count without checking available memory makes things worse rather than better.
Check whether the server has swap. Without it, memory pressure produces process kills instead of slowdowns, as covered in the new VPS checklist.
A segfault in a PHP extension will kill a worker. The log names the extension. This is rare but appears after PHP upgrades or when using less common extensions.
Configuration reload failures after an edit. If you changed the pool configuration and reloaded, a syntax error may have left the service in a bad state.
Disk full, which prevents PHP-FPM from writing to sockets or logs and produces failures that look unrelated to disk.
Automatic restarts from a process manager reacting to failures, producing a cycle of brief 502 windows.
The pattern to recognise: if 502s are total rather than intermittent and the service is not running, it is a crash. If they are intermittent under load and the service is running, it is worker exhaustion. Those are different investigations and conflating them wastes time.
| Layer | Typical symptom | Log to check | First action |
|---|---|---|---|
| CDN to origin | Branded CDN error page | CDN dashboard | Bypass via hosts file |
| Origin firewall | 502 for all, direct access works | Firewall or security plugin log | Allow CDN IP ranges |
| CDN SSL mismatch | Started after certificate change | CDN dashboard | Check origin certificate validity |
| nginx to PHP-FPM socket | Total, immediate 502 | nginx error log | Verify socket path matches |
| Worker pool exhausted | Intermittent, load-correlated | PHP-FPM log | Fix caching first, then raise workers |
| Script timeout | Specific operations only | nginx and PHP-FPM logs | Move task out of request cycle |
| PHP-FPM crashed | Total, service not running | PHP-FPM and system log | Check memory and disk |
| Out of memory | 502s plus process kills | System log | Add swap, lower max_children |
| Disk full | Varied, odd failures | System log | Free space, add alerting |
Cause: misconfiguration after a change
A large share of 502s appear immediately after a change, which makes the recent-change question the most efficient first question.
After a PHP version upgrade. The socket path changes and nginx still points at the old one. Update the fastcgi_pass directive to match the new version's socket.
After a server configuration edit. A syntax error, a wrong upstream definition, or a reload that failed silently. Validate configuration before reloading, and check the service actually restarted rather than assuming.
After enabling a CDN or proxy. Origin firewall rules, SSL mode mismatch, or the origin only accepting connections from specific addresses.
After a security plugin update. Some add server-level rules or rate limits that block the proxy or interfere with request handling.
After a migration. Configuration referencing paths, sockets or ports from the previous server.
After a certificate renewal. If a CDN validates the origin certificate strictly, a renewal that did not complete properly breaks the connection.
The efficient move whenever a 502 appears suddenly: ask what changed in the last twenty-four hours, and check that first. It is right often enough to justify asking before opening any log.
Preventing recurrence
Get caching verified, not just installed. Most worker exhaustion is a caching failure wearing a different hat. Check response headers for a cache hit rather than trusting the plugin dashboard, as covered in the WordPress speed guide.
Size the worker pool to your memory. Available RAM divided by average per-process memory, with headroom. Too high causes OOM kills; too low causes queueing.
Add swap on a VPS, so memory pressure degrades performance rather than killing processes.
Monitor disk space with an alert at 80%.
Align your timeouts. Nginx, PHP-FPM and PHP should be consistent, with nginx's not shorter than PHP's.
Set timeouts on external API calls in your code and check that plugins making remote requests do the same. A hanging external call is one of the nastiest causes because it is invisible in normal operation.
Run long jobs outside the request cycle. WP-CLI or a background queue for imports, backups and bulk operations.
Monitor PHP-FPM worker utilisation, not just uptime. Approaching the ceiling is a warning you can act on; hitting it is an outage.
Monitor from outside the server, and monitor a page that exercises PHP rather than a static file, since a static file will serve happily while PHP is completely down.
FAQs
What does 502 Bad Gateway mean?
It means a server acting as a gateway or proxy asked an upstream server for a response and did not receive a valid one. The server returning the error is not the one that failed. On a WordPress site it usually means PHP is not answering, either because PHP-FPM is down, has no free workers, or a script died mid-request.
Is a 502 error my fault or the host's?
It depends which gateway relationship failed. A 502 from a CDN usually means your origin did not answer. A 502 from nginx usually means PHP-FPM did not answer, which can be a resource problem you can influence, a configuration error, or a server-level failure. Bypassing the CDN and checking whether other sites on the account are affected narrows it quickly.
How do I fix a 502 error on WordPress?
Work down the stack. Bypass any CDN to see whether the origin is at fault, check whether PHP-FPM is running, verify the socket path matches between nginx and PHP-FPM, then check whether the worker pool is exhausted. Read both the nginx error log and the PHP-FPM log, since together they usually name the cause.
Why do I get 502 errors only during busy periods?
Because the PHP-FPM worker pool is exhausted. Each worker handles one request at a time, and when all are busy new requests queue until nginx gives up. The underlying cause is usually that caching is not working, so every visitor consumes a worker instead of being served a cached page.
Should I increase pm.max_children to fix 502 errors?
Only after addressing why workers are being consumed. Fix caching first, then slow queries and pages, then external API calls without timeouts. Raising the worker count without reducing load moves the failure point, and setting it beyond what your RAM supports causes memory exhaustion, turning a queueing problem into a crashing one.
Why did 502 errors start right after upgrading PHP?
Almost certainly because the PHP-FPM socket path includes the version number and your nginx configuration still points at the old one. Update the fastcgi_pass directive to reference the new version's socket, then reload nginx. This is one of the most common causes of a sudden total 502 on a VPS.
Can Cloudflare cause 502 errors?
Yes, in several ways: your origin firewall blocking Cloudflare's IP ranges, an SSL mode mismatch where Cloudflare validates an origin certificate that is expired or self-signed, or the origin being unreachable from Cloudflare's network. Bypass Cloudflare using your hosts file to determine whether the origin itself is healthy.
What is the difference between 502 and 504?
Both involve an upstream failure. A 502 generally means the upstream returned an invalid or empty response, while a 504 means it was contacted but did not respond within the timeout. In practice the distinction blurs, since different proxies return different codes for similar conditions, and the diagnostic approach is the same.
What is the difference between 500 and 502?
A 500 means the server processing the request encountered a fault itself, typically a PHP fatal error. A 502 means the server could not get a usable response from an upstream component. Apache with mod_php tends to produce 500s where an nginx and PHP-FPM stack produces 502s for a similar underlying fault.
Why do imports and backups cause 502 errors?
Because they exceed one of the timeouts in the chain: PHP's execution time, PHP-FPM's terminate timeout, nginx's read timeout, or a CDN timeout you may not be able to change. Rather than raising all of them, run long operations through WP-CLI or a background queue, where they are not subject to request timeouts.
How do I check if PHP-FPM is running?
On a VPS, check the service status through your init system and read the service log if it is not running. On shared hosting you have no direct access, so check whether other sites on the account are also failing, which distinguishes a server-level problem from a site-level one, and give that information to support.
Does clearing my browser cache fix a 502?
No. A 502 is generated server-side and the browser is not involved in the failure. Clearing cache or trying a different browser will not change anything, which is why that advice, common as it is, wastes time that would be better spent reading the server logs.
Conclusion
The single most useful reframe is that a 502 is about a gap between two components, not about one component being broken. The server showing you the error is working; something behind it is not.
So the sequence is elimination rather than guessing. Bypass the CDN, which resolves half the possibilities in one test. Check whether PHP-FPM is running, which resolves most of the rest. Then read the nginx and PHP-FPM logs together, because one tells you what was attempted and the other tells you what happened.
Two patterns cover most real cases. Intermittent 502s correlated with traffic are worker exhaustion, and the actual fix is almost always caching rather than raising pm.max_children. Total 502s that started suddenly are configuration, and the first question is what changed — with a PHP version upgrade and its moved socket path being the most common single answer.
Long-running operations deserve their own treatment. Imports and backups through a browser are subject to four separate timeouts and will fail again at a larger data volume. Move them to WP-CLI or a queue rather than raising limits until they fit.
And monitor a page that exercises PHP. A static-file uptime check will report everything is fine while PHP is entirely down.
HostCloud runs LiteSpeed with server-level caching and tuned PHP pools on Indian infrastructure, with error log access from the panel and PHP version switching that keeps the stack consistent. Plans from ₹99 a month at https://hostcloud.in.
