502 Bad Gateway Error: Causes and How to Fix It
A 502 Bad Gateway means your web server got a response from something upstream - PHP-FPM, a backend app, or Cloudflare's edge - and that response was garbage, empty, or never came at all. It's rarely your homepage that's broken; it's the layer just behind it. Here's how to find which layer and fix it.
What 502 actually means
Every request to your site passes through at least two layers: a front-facing web server (Apache, LiteSpeed, Nginx, or Cloudflare's proxy) and a backend that actually generates the page (PHP-FPM, a Node process, or your origin server). A 502 fires when the front layer is working fine but the backend it's talking to crashed, timed out, or sent back something the front layer couldn't parse. That's the key difference from a 500: a 500 says "I ran your code and it errored." A 502 says "I couldn't even get a proper answer out of the thing I forward requests to."
On shared cPanel hosting this usually points to PHP-FPM. On a site behind Cloudflare, it usually points to something between Cloudflare and your origin server. On a custom app server, it's the app process itself.
Cause 1: PHP-FPM crashed or ran out of workers
Most cPanel and LiteSpeed hosting runs PHP through PHP-FPM, a pool of worker processes that hand off requests to PHP. If every worker is busy - because of a traffic spike, a slow database query, or a plugin holding connections open - new requests get refused, and the web server in front reports a 502 instead of waiting forever.
Check the PHP-FPM error log for your domain, usually at:
/var/log/php-fpm/www-error.log
# or, on cPanel with EasyApache:
/usr/local/apache/logs/error_log
Look for lines like server reached pm.max_children setting. That confirms the pool is undersized for your traffic. If you're on a VPS or a plan where you can adjust it, raise pm.max_children in the pool config (usually /etc/opt/remi/php{version}/php-fpm.d/*.conf or via cPanel's MultiPHP INI Editor for memory/timeout settings), then restart PHP-FPM:
sudo systemctl restart php-fpm
On shared hosting where you can't touch pool settings directly, this is usually a sign you've outgrown the plan's resource limits - see the CloudLinux angle below.
Cause 2: CloudLinux is throttling the account
If your hosting runs CloudLinux (most shared cPanel hosting does), a 502 can actually be a resource limit in disguise. When an account hits its entry process limit or CPU cap, CloudLinux can kill the PHP process mid-request instead of returning a clean 508. The front-end server then has nothing to relay back, and you get a 502.
Check current usage in cPanel under Resource Usage, or ask your host to check lve stats for the account. If EP (entry processes) is regularly maxed out, the fix is either reducing concurrent long-running scripts (cron jobs, API calls, unoptimized plugins) or moving to a plan with a higher LVE allowance.
Cause 3: A plugin or script is timing out
A single slow PHP process - a plugin calling a slow external API, a huge unindexed database query, an image being resized - can hold a worker past its timeout. FPM kills it, and the request that was waiting on it gets a 502.
To find the culprit, deactivate plugins one at a time (or use WP-CLI to do it without touching wp-admin if wp-admin itself is timing out):
wp plugin deactivate --all
wp plugin activate akismet classic-editor
# reactivate one by one, reloading the page each time
If the 502 disappears after deactivating a specific plugin, that's your cause. Common repeat offenders are backup plugins running mid-request, SEO plugins doing live sitemap generation, and anything that calls a third-party API synchronously on page load.
Cause 4: Cloudflare can't reach your origin properly
If you're behind Cloudflare, a 502 (sometimes shown as Cloudflare's own error page rather than your site's) means Cloudflare's edge got a broken response from your actual server. This is different from Cloudflare's 521/522/525 codes, which mean the origin refused the connection entirely - a 502 here means the origin answered, just badly.
Common causes:
- Your origin server's own PHP-FPM or Apache is the one actually failing (work through causes 1-3 first, on the origin itself)
- A firewall or ModSecurity rule on the origin is silently dropping some requests but not others
- SSL mode mismatch - if Cloudflare's SSL mode is set to Full (strict) but your origin cert is self-signed or expired, some request types fail while others pass
Test by bypassing Cloudflare temporarily - hit the origin IP directly with a hosts file entry, or grey-cloud the DNS record - and see if the 502 still happens. If it goes away, the origin is fine and the issue is in Cloudflare's SSL mode or a firewall rule between the two.
Cause 5: mod_security or a WAF is blocking the backend response
Less common, but it happens: a security module inspects the response coming back from PHP-FPM or your app, decides something in it looks wrong (a header, a chunked-encoding quirk), and drops it instead of passing it through. Check /usr/local/apache/logs/error_log or your WAF's own log for the same timestamp as the 502 - if you see a rule ID logged right next to it, that's your answer. Temporarily whitelisting the specific rule ID for that path confirms it before you make the exception permanent.
Quick diagnosis order
| Check | What it tells you |
|---|---|
| PHP-FPM / Apache error log timestamp match | Confirms it's a backend crash, not a network issue |
| cPanel Resource Usage / LVE stats | Rules a CloudLinux resource cap in or out |
| Deactivate plugins one by one | Isolates a specific plugin causing timeouts |
| Bypass Cloudflare (grey-cloud DNS) | Separates an origin problem from a Cloudflare-side one |
| WAF/ModSecurity log at same timestamp | Confirms a security rule is dropping the response |
Prevention
- Watch Resource Usage in cPanel before traffic spikes turn into 502s - don't wait for the error to check
- Cache aggressively (page cache plus object cache) so PHP-FPM isn't regenerating every page from scratch under load
- Move heavy jobs (backups, bulk emails, report generation) to WP-Cron scheduled for off-peak hours instead of running them inline on page load
- If you're on Cloudflare, set SSL mode to Full (strict) only once your origin cert is valid and auto-renewing - a mismatched mode causes intermittent 502s that are maddening to trace
- Keep plugins updated - most timeout-related bugs get fixed in later releases
A 502 almost always has a clean paper trail once you know which log to open. Start at the backend (PHP-FPM or Apache error log), work outward to CloudLinux limits, then to Cloudflare - in that order - and you'll usually find the actual failure within a few minutes instead of guessing at plugin conflicts first.
Frequently asked questions
Is a 502 error the same as a 500 error?
No. A 500 means the backend ran your code and it threw an error. A 502 means the front-facing server couldn't get a valid response from the backend at all - it crashed, timed out, or returned something unparseable.
Why does my site show 502 only sometimes, not always?
Intermittent 502s usually point to a resource limit (PHP-FPM workers maxing out under load, or a CloudLinux entry process cap) or an SSL mode mismatch behind Cloudflare - both fail only when a specific threshold or request type is hit, not on every request.
Can a caching or backup plugin cause a 502 error?
Indirectly, yes. If a plugin runs a heavy process synchronously on page load (like regenerating a full-site cache), it can hold a PHP-FPM worker past its timeout and trigger a 502 for the visitor waiting on that request.
Does restarting PHP-FPM fix a 502 error?
It can clear a stuck state temporarily, but if the underlying cause is a resource limit or a slow plugin, the 502 will come back under the same conditions. Restarting buys you time to find the actual cause, not a permanent fix.
How do I check if Cloudflare or my origin server is causing the 502?
Grey-cloud the DNS record in Cloudflare (or edit your local hosts file to hit the origin IP directly) and reload the site. If the 502 disappears, the problem is between Cloudflare and your origin - likely an SSL mode mismatch or firewall rule. If it persists, the origin server itself is failing.