The 502 Bad Gateway error has a precise technical definition from the IETF: a server acting as a gateway or proxy received an invalid response from an upstream server it accessed while attempting to fulfill a request. The critical word is upstream.
Your browser connects to a front-facing server — Nginx, Apache, Cloudflare, an AWS load balancer. That front-facing server tries to get a response from something behind it: your PHP-FPM process, a Node.js app, a Django backend. If the backend returns garbage, nothing, or refuses the connection entirely, the gateway has no valid response to give your browser. So it returns 502.
A 502 is almost never caused by the browser or the visitor. It is a mid-tier server failure. The client is innocent. The fix is on the server side.
Locating the Break: Where Your Stack Can Fail
A 502 can fire at any gateway in your chain. Cloudflare cannot reach your origin. Nginx cannot reach PHP-FPM. The app server cannot reach the database. You cannot fix what you have not located.
The fastest location test: run one of these commands and read the first error message that appears. The log line usually names the exact failure type within the first line.
| # Nginx error log (most common starting point)
tail -30 /var/log/nginx/error.log
# PHP-FPM log tail -30 /var/log/php8.2-fpm.log
# System log for OOM kills grep -i ‘killed process’ /var/log/syslog | tail -10 |
Do not skip straight to configuration changes without reading the logs first. The error log tells you exactly which layer failed. Three minutes of reading saves an hour of guessing.
The 60-Second Triage Protocol
When a site is down, sequencing matters. Start with the most common cause and work outward. Jumping to CDN settings before checking whether PHP-FPM is running is the leading cause of long outages.
First action, always: systemctl status php8.2-fpm and check the process list. On WordPress and most PHP sites, a crashed or worker-exhausted PHP-FPM pool causes over 70% of 502 errors. If the process is dead, restart it first and check the logs afterward.
Cause Probability by Stack Type
Not all causes are equally likely on all setups. A cause that fires constantly on WordPress rarely matters on a Node.js app. Cross-reference your stack against this matrix before making changes.
The PHP-FPM Worker Pool Problem
The most common cause of 502 on PHP stacks is straightforward: you have 5 PHP-FPM workers configured and 12 concurrent requests arrive. The worker pool is full. Nginx tries to hand off request 6 through 12, gets nothing back, and returns 502 to all of them.
The error log message that confirms this is exactly:
| connect() to unix:/var/run/php/php8.2-fpm.sock failed
(11: Resource temporarily unavailable) while connecting to upstream |
The correct number of PHP-FPM workers is based on your server’s available RAM and how much memory each PHP process consumes. A rough calculation:
| # Find average PHP process memory usage:
ps –no-headers -o ‘rss,cmd’ -C php-fpm8.2 | awk ‘{ sum+=$1 } END { print int(sum/NR/1024) “MB per process” }’
# Then: max_children = (total RAM – OS/Nginx overhead) / per-process size # Example: 2GB RAM – 512MB overhead = 1536MB / 50MB per process = 30 workers |
The Configuration Fixes: Exact Before and After
Three configuration changes resolve the majority of 502 errors on self-managed servers. Each one addresses a specific failure mode visible in the error logs.
Nginx Timeout: When the Backend Is Alive but Slow
If your log shows upstream timed out (110: Connection timed out) rather than a connection refused error, the problem is a timeout mismatch, not a crashed process. The backend is running but taking longer than Nginx will wait. The solution is raising the timeout values:
| # In your Nginx server block or location block:
proxy_read_timeout 120s;Â Â Â # was 60s by default proxy_connect_timeout 30s;Â # was 10s proxy_send_timeout 120s;
# After editing, always validate before reloading: nginx -t systemctl reload nginx |
Raising timeouts is a short-term fix, not a long-term solution. A backend that regularly takes 90 seconds to respond has a performance problem — a slow database query, an uncached external API call, or an unoptimized operation that will eventually cause timeouts even with higher values. Fix the underlying slowness alongside raising the timeout.
PHP-FPM Process Manager: pm = ondemand vs dynamic
The pm = dynamic mode pre-creates workers and scales between min_spare_servers and max_spare_servers. On servers with limited RAM, pm = ondemand creates workers only when needed and kills them after pm.process_idle_timeout seconds. For most production WordPress sites with predictable traffic, dynamic is better. For low-memory VPS servers with spiky traffic, ondemand wastes less RAM between peaks.
When Cloudflare Is Involved: Isolating CDN from Origin Issues
When Cloudflare sits in front of your server, a 502 can mean one of two completely different things: Cloudflare cannot reach your origin server, or your origin is returning something Cloudflare cannot interpret (which it logs as a 520 error, not a standard 502). Before modifying any server configuration, determine which scenario you have.
The fastest isolation test:
- Go to the Cloudflare dashboard for the affected domain
- Click Overview, then scroll to Advanced Actions
- Click Pause Cloudflare on Site
- Test whether the site loads by visiting it directly
If the site loads after pausing Cloudflare, your origin server is healthy and the problem is the connection between Cloudflare and your origin. Common causes: your origin firewall is blocking Cloudflare’s IP ranges, your origin SSL certificate is not valid for Cloudflare’s Full (Strict) mode, or your origin IP changed without updating Cloudflare’s DNS.
If the site still shows an error after pausing Cloudflare, the problem is in your origin server and the triage protocol from Figure 2 applies directly.
Cloudflare publishes its IP address ranges at cloudflare.com/ips. If you have a firewall on your origin server, ensure all Cloudflare IP ranges are explicitly allowed. Origin servers that block all traffic except from known sources are a very common cause of Cloudflare-specific 502 errors after security hardening.
WordPress Specifics: Plugins, Memory, and Maintenance Mode
WordPress 502 errors have three causes that do not apply to other stacks. Each has a distinct symptom and a different fix.
Plugin causing PHP to crash or exceed limits
A single plugin with a memory leak, an infinite loop, or an extremely slow database query can exhaust all available PHP-FPM workers. The symptom is 502 errors that appear during specific actions (importing products, regenerating images, running a bulk operation) rather than under general traffic load. The fix is isolation:
| # Via FTP or server file manager:
# Rename the plugins folder to disable all plugins at once mv /var/www/html/wp-content/plugins /var/www/html/wp-content/plugins_OFF
# Test the site. If it loads, a plugin was the cause. # Restore and reactivate one by one: mv /var/www/html/wp-content/plugins_OFF /var/www/html/wp-content/plugins |
WordPress stuck in maintenance mode
When a WordPress update is interrupted (browser closed, timeout during upgrade), a .maintenance file is left in the WordPress root directory. This file intentionally triggers a 503 Service Unavailable response, but some server configurations return it as a 502. Delete the file:
| rm /var/www/html/.maintenance
# Then reload the site |
wp-cron overloading PHP workers
WordPress’s built-in cron system (wp-cron) runs scheduled tasks by triggering a PHP request on every page load if tasks are due. On high-traffic sites, this means dozens of background PHP processes can spawn simultaneously, exhausting the PHP-FPM worker pool under load. Disable wp-cron in wp-config.php and replace it with a real server cron:
| // In wp-config.php, add before the final require_once:
define(‘DISABLE_WP_CRON’, true);
// Then add to crontab (crontab -e): */5 * * * * curl -s https://yourdomain.com/wp-cron.php > /dev/null 2>&1 |
Platform Quick Reference
Different technology stacks need different commands. These are the exact steps for six common environments.
502 in Context: The Full 5xx Error Family and the Business Cost
502 vs 504: The Distinction That Changes the Fix
These two errors look nearly identical to visitors and share similar root causes. The difference is specific and matters for the fix. A 502 means the upstream returned something invalid, returned nothing at all, or refused the connection. A 504 means the upstream was reachable and started responding but took too long. The gateway gave up waiting.
The practical difference: 502 usually means restart the process or fix the configuration. 504 usually means raise timeout values and optimize the slow operation. Running the wrong fix on the wrong error wastes time.
SEO and Monitoring: What Happens to Rankings During a 502
A brief 502 spike, even one lasting an hour, has essentially no lasting SEO impact. Googlebot is patient and will retry. Problems start when a 502 persists for more than 24 hours. After that, affected pages begin accumulating crawl errors in Google Search Console. After 48 to 72 hours, Google may start temporarily deindexing pages it cannot access.
The recovery after a prolonged 502 is not automatic. After the error clears, open Google Search Console, navigate to URL Inspection, and submit your key pages for re-indexing. This prompts Googlebot to re-crawl and clears the crawl error record faster than waiting for the natural crawl cycle.
The most valuable investment after your first 502 is setting up uptime monitoring before the second one. UptimeRobot free tier monitors up to 50 URLs every 5 minutes and sends email or Slack alerts when a 5xx error is detected. You want to know about a 502 in minutes, not hours.
Prevention: What to Configure Once to Avoid 502s at Scale
Most repeat 502 outages are preventable. These are the four changes that eliminate the most common causes.
- Set PHP-FPM pm.max_children correctly for your RAM. Calculate based on observed per-process memory usage, not guesswork. Monitor with pm.status_path and a real-time dashboard if you run high traffic.
- Enable Nginx keepalive connections to PHP-FPM upstream. This reduces the overhead of establishing a new connection for each PHP request and provides graceful fallback when one upstream fails.
- Configure uptime monitoring with alerts to your phone. A 502 you discover in 3 minutes costs far less than one discovered by a customer complaint 45 minutes later.
- Set pm.max_requests = 500 in your PHP-FPM pool configuration. This recycles workers after 500 requests, preventing slow memory leaks from plugins and themes from gradually exhausting all workers over hours of operation.
Frequently Asked Questions
Can a visitor cause a 502 error?
No. A 502 error is always a server-side failure. Visitors cannot produce a 502 through normal browsing behavior. The closest a visitor can get is triggering a condition that exposes a pre-existing problem, such as making a request that causes a slow database query, but the underlying issue is on the server. Any visitor who sees a 502 is a victim of it, not the cause.
My site works in incognito but not in my regular browser. Is it a 502?
If the site loads in incognito, the error is almost certainly not a 502. A 502 affects all visitors equally because it fires on the server before any response reaches the browser. Browser-specific issues are typically caused by cached cookies, stale DNS entries in Chrome’s internal cache, or browser extensions interfering with requests. Clear Chrome’s DNS cache at chrome://net-internals/#dns and clear cookies for the domain.
How do I tell if a 502 is coming from Cloudflare or from my origin server?
Look at the error page design. Cloudflare 502 pages include a Cloudflare logo or branding and typically show a Ray ID in the footer. Origin server 502 pages look like your hosting provider’s default error page or a plain white browser error. The fastest technical test is pausing Cloudflare in the dashboard and testing the site directly. If the error disappears, Cloudflare is involved. If it persists, the origin is the source.
PHP-FPM shows as running but the site still returns 502. What else should I check?
If the process is running but returning 502, check these in order: the socket path or port in your Nginx proxy_pass directive does not match what PHP-FPM is actually listening on; the PHP-FPM worker pool is full (check the error log for Resource temporarily unavailable); the PHP script is exceeding the proxy_read_timeout value (check for upstream timed out in the Nginx log); or the PHP process is running but crashing on specific requests due to a memory or execution time limit.
Does a 502 hurt my Google search rankings?
A 502 lasting under an hour on a site Google crawls infrequently has negligible SEO impact. Googlebot will retry on its next crawl cycle. A 502 lasting 24 to 48 hours causes crawl errors to accumulate in Google Search Console and may cause affected pages to be temporarily deindexed. Rankings typically recover within one to two weeks after the error is resolved, provided the pages are resubmitted via URL Inspection in Search Console to prompt re-crawling.
I restarted PHP-FPM and the 502 went away. How do I stop it happening again?
A 502 that resolves with a PHP-FPM restart and recurs periodically is almost always caused by insufficient workers for your traffic level, a memory leak in a plugin gradually consuming available workers over time, or pm.max_requests not being set (allowing workers to accumulate memory until they are killed). Increase pm.max_children based on your available RAM, set pm.max_requests to 500, and install uptime monitoring to catch the next occurrence within minutes rather than after prolonged downtime.
