Troubleshooting guide · http-status · Published 2026-08-15 · 4 min read

HTTP 502 bad gateway

HTTP 502 bad gateway guide: cause chain from PHP-FPM crashes to origin timeouts, the ordered fix list, and how to verify the origin after a 502.

Flat editorial illustration showing a lantern-style status readout with a neat row of stacked directory rails, each rail marked with an abstract tally.
Illustration: this article at a glance.

What a 502 means

A 502 Bad Gateway is the honest middleman gossip: a proxy or gateway (nginx, Apache with proxy_pass, Cloudflare, a load balancer) tried to forward your request to an upstream server, and the upstream answered with something unusable: a protocol error, a timeout, a TCP refusal, or a response that ended mid-stream. The client cannot tell whether the upstream simply crashed at that moment or the route is misconfigured; the fix order asks exactly that question.

Editorial close-up illustration showing a lantern-style status readout with a neat row of stacked directory rails, each rail marked with an abstract tally.
Illustration: a closer look at the technique described above.
Product chainUpstreamTypical 502 look
Cloudflare in front of your originYour web server or PM2Cloudflare-branded error, or your host's 502 splash
nginx reverse proxyPHP-FPM or a Node/PHP app502 Bad Gateway plain text
Apache with mod_proxyApplication on port 8080/3000Browser generic page

Common causes

The ordered fix

  1. Repeat the 502 after a pause. Make a couple of page loads in a private window separated by a second. If it transiently 200s, the pool is flapping; if it never succeeds, the route or process is down.
  2. Check the process. Confirm the app process and the socket it listens on are alive and up:

- systemctl status php-fpm and systemctl status nginx on a systemd host.

- curl the app directly, bypassing the proxy: curl localhost:8080/health.

- ss -tlnp | grep :8080 to confirm the port is bound.

  1. Read both logs in order. The nginx error log records upstream timed out or no live upstreams; the PHP-FPM or app log then tells you the underlying failure (out of memory, missing file, a fatal exception).
  2. Restart in the right order the upstream first, wait for it to become healthy, then the proxy. If the proxy comes up first it floods the not-yet-listening port with 502s.
  3. Beware timeouts. If the workload is a legitimately long job, raise the proxy timeout (nginx proxy_read_timeout), move the work to background, or stream the response early.
  4. Check the deploy. A 502 that starts exactly after a release means the binary failed to boot. Roll back the app (not the proxy) and watch the app log on the old version.
  5. On Cloudflare, a 522 is the edge-to-origin variant, while a 502 means the origin answered in an unusable way. Check the origin logs and confirm the origin actually answers the IP Cloudflare sends.

Verify

# Is the origin up at all, bypassing the gateway?
curl -i http://127.0.0.1:8080/api/health
# 200 OK means the app is fine and the proxy/bind is the problem

# From the proxy, is the same request a 502 again?
curl -sI https://example.com/api/health
HTTP/2 502

Prevention

When to involve a professional

If the upstream is healthy on 127.0.0.1 and the gateway still 502s, the issue is a binary mismatch between the bind and the proxy: IPv6, port, or a wrong hostname. A host or a senior sysadmin can diff the two configs in minutes; do not reinstall the app over it.

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