Troubleshooting guide · wordpress · Published 2026-08-15 · 4 min read

WordPress site returns 502 bad gateway

Fix a WordPress 502 bad gateway: check PHP-FPM worker health, fastcgi logs, worker and timeout settings, then verify via WP-CLI.

Symptoms

The site answers 502 Bad Gateway from nginx with a plain page, or a host-branded gateway page. The front end and admin are usually both down, because the admin runs the same PHP-FPM pool. If a 522 appears from another network, that is the edge-to-origin variant in the Cloudflare family, while a 502 means the origin answered in an unusable way. The 502 bad gateway article covers the proxy-level view; here the fixes are PHP-FPM and WordPress specific.

Common causes

Fix in order

  1. Confirm the 502 is live, not cached. A CDN or cache layer can serve a stale 502 for a while after PHP recovers. Test curl -sI from a shell outside the CDN; then look at nginx logs:
tail -n 50 /var/log/nginx/error.log

Find the exact line upstream timed out or connect() to ... 9000 failed. The message names the socket path and often the worker.

  1. Restart PHP-FPM first. The proxy restart alone can make it worse: nginx comes up, floods a dead pool, and worsens the 502 string. Restart the pool in the order that heals fastest:
systemctl restart php-fpm
systemctl restart nginx

If the restart clears it, the worker had wedged. Now find out why before it happens again.

  1. Read the WordPress log for the underlying fatal. A plugin or theme process dying with a fatal error exits the worker, which on a busy site looks identical to a hang. Enable the log as in white screen of death and read wp-content/debug.log plus tail the PHP-FPM error log together; a segfault, Unable to allocate memory, or a fatal is the real cause.
  2. Size the pool to the site. In the PHP-FPM pool config:
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500

A safe starting rule: max_children = (memory available for PHP) / (typical peak per worker). If each worker peaks around 128 MB and you want room for 20 concurrent requests, budget roughly 2.5 GB. max_requests restarts every worker before its memory leaks grow, so set a live value such as 500.

  1. Raise the fastcgi timeouts for your real work.
location ~ \.php$ {
    fastcgi_read_timeout 300;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
}

Only raise them to the duration your slowest legitimate request needs. An import polled for 10 minutes will 502 at 60 seconds no matter the pool health, because the timeout kills the worker before the job.

  1. Test through WP-CLI. WP-CLI runs outside PHP-FPM, so wp option get home working from a shell proves files, config, and database are fine and the fault is the pool or proxy. If WP-CLI fails with the same error, the runtime itself is the problem (module missing, PHP version too new).
  2. Verify the rescue: load the site and the admin in a private window, then run a health loop.
TestCommandWhat it proves
Pool statuscurl -sI https://example.com/wp-login.php200 not 502
PHP-FPM statussystemctl is-active php-fpmrunning
CLI pathwp option get home --allow-rootconfig + DB fine
Log tailtail -n 20 /var/log/php-fpm/error.logstory after the fix

Prevention

When to involve a professional

A 502 at every page even after a clean pool restart, with WP-CLI working, points to a proxy misconfiguration: wrong socket path, a FastCGI module missing, or a firewall dropping the upstream port. That is a host-level fix best done by the host, not by editing the website.

Need a website built, fixed, optimised, migrated or replaced?

This technical resource is written by CSMBAC, a small design and development studio. If you would rather hand the problem to a professional, the website service page explains how we build enquiry-ready websites.

Explore website services