गाइड · डाउनटाइम और एरर

How to Fix a 502 Bad Gateway Error (nginx, Apache, PHP-FPM, CDN)

What a 502 Bad Gateway really means, how to find the failing upstream with logs and curl, and fixes for nginx, Apache, PHP-FPM, Node and Cloudflare setups.

लेखक: SiteDownCheck संपादकीय टीम · अपडेट: अक्टूबर 4, 2026 · 8 मिनट पढ़ने में

A 502 Bad Gateway means a server acting as a gateway or proxy received an invalid response, or no response, from the server behind it. The page you see is not the real problem; it is the proxy reporting that something upstream broke. This guide shows how to identify which hop failed, read the log line that names the cause, and fix the common versions of the problem.

The definition comes from HTTP semantics (RFC 9110): a gateway got an invalid response from an inbound server while trying to fulfil the request. See also the HTTP 502 reference.

First, work out who is the "gateway"

In a modern site there are often several proxies stacked in a row:

Browser -> CDN (e.g. Cloudflare) -> load balancer -> nginx/Apache -> PHP-FPM / Node / Gunicorn -> database

Any element that forwards a request can generate a 502 for the one behind it. So the first question is which layer produced the page. Clues:

  • The error page has a CDN logo, a Ray ID, or says "Bad gateway" with a host list: the CDN itself generated it. Cloudflare commonly shows 502 when its edge cannot get a valid response, but origin problems often show as 52x codes instead (see Cloudflare 520 to 526 errors).
  • A bare, plain 502 Bad Gateway with nginx at the bottom: nginx is your gateway.
  • A page titled "Proxy Error": Apache with mod_proxy.
  • Response headers show Server: and Via: values. Check them:
curl -sI https://example.com/ | head -n 15

The HTTP Header Checker shows the same information from outside your network.

Read the error log, which names the cause

Almost every 502 has a precise line in the gateway's error log. This is the fastest diagnostic available.

# nginx
sudo tail -n 100 /var/log/nginx/error.log

# Apache (Debian/Ubuntu path; RHEL uses /var/log/httpd/error_log)
sudo tail -n 100 /var/log/apache2/error.log

# live view while you reproduce the error
sudo tail -f /var/log/nginx/error.log

The common nginx messages and what they mean:

Log messageMeaningWhere to look
connect() failed (111: Connection refused) while connecting to upstreamNothing is listening at the upstream addressBackend service stopped or wrong socket/port
connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory)Socket path does not existPHP version mismatch or FPM down
connect() to unix:... failed (13: Permission denied)nginx user cannot access the socketSocket owner/group, listen.owner
upstream prematurely closed connection while reading response headerBackend crashed or was killed mid-requestApp crash, OOM kill, segfault
recv() failed (104: Connection reset by peer)Backend dropped the connectionWorker restarts, request limits
upstream sent too big header while reading response header from upstreamResponse headers exceed bufferIncrease buffers, reduce cookie size
no live upstreams while connecting to upstreamAll servers in an upstream group are marked failedBackends down or failing health thresholds

Note that upstream timed out is a different animal: that yields a 504, covered in fix 504 Gateway Timeout.

Fixes by stack

PHP-FPM behind nginx or Apache

This is the most common situation on WordPress and Laravel servers.

sudo systemctl status php8.3-fpm        # use your version
sudo journalctl -u php8.3-fpm --since "1 hour ago"
sudo tail -n 50 /var/log/php8.3-fpm.log
ls -l /run/php/

Check the following, in order:

  1. Is FPM running? If not, start it and read why it stopped.
  2. Does the socket or port in nginx match FPM? The fastcgi_pass value must equal listen in the pool file (/etc/php/8.3/fpm/pool.d/www.conf). After a PHP upgrade, the socket name changes, and nginx is still pointing at the old one. That is a classic post-upgrade 502.
  3. Are workers exhausted? A log line such as server reached pm.max_children setting (N), consider raising it means all workers were busy. Raising pm.max_children helps only if memory allows. Estimate: max_children is roughly the memory available for PHP divided by the average memory of one worker (measure with ps --no-headers -o rss -C php-fpm8.3). Setting it higher than RAM allows trades a 502 for the OOM killer.
  4. Did workers crash? A segfault in dmesg -T | grep -i segfault often points to a faulty PHP extension, such as an incompatible opcache or a third-party module.
  5. Is a worker being killed for running too long? request_terminate_timeout kills a script, and the proxy sees a broken connection.

After changing config, validate and reload:

sudo nginx -t && sudo systemctl reload nginx
sudo php-fpm8.3 -t && sudo systemctl restart php8.3-fpm

Node.js, Python (Gunicorn, uWSGI) and other app servers

The pattern is the same: the proxy cannot reach the process.

sudo systemctl status myapp
sudo ss -tlnp | grep 3000        # is anything listening on the expected port?
curl -sv http://127.0.0.1:3000/ -o /dev/null
journalctl -u myapp -n 100 --no-pager

If curl to the app directly fails, nginx is not at fault. Typical causes are an uncaught exception that crashed the process with no supervisor restarting it, the app binding to 127.0.0.1 while nginx proxies to another address (or to a container's internal IP), or an environment variable missing after a redeploy. Run the app under systemd, PM2 or a container restart policy so that crashes self-heal.

Apache with mod_proxy or PHP-FPM via proxy_fcgi

Look for "AH01114: HTTP: failed to make connection to backend" or "AH00957" in the error log. Both mean the backend address is wrong or down. If workers are saturated you may see "server reached MaxRequestWorkers setting", but that more typically produces slow responses or 503. Confirm the ProxyPass target and the backend service.

Large headers and cookies

If the log says upstream sent too big header, the backend returned more header data than nginx's buffer. This often follows a login plugin that sets huge cookies or debug headers. Increase the buffers for the relevant module:

# for FastCGI (PHP-FPM)
fastcgi_buffer_size 32k;
fastcgi_buffers 16 16k;

# for proxy_pass upstreams
proxy_buffer_size 16k;
proxy_buffers 8 16k;

Reducing the cookie or header size at the source is the better long-term fix.

Cloudflare and other CDNs

When Cloudflare shows a branded 502, test the origin directly as in the earlier tip. Cloudflare's published guidance also lists reasons such as an origin that sends malformed headers or resets connections. If your page shows 52x codes, use the Cloudflare एरर चेकर. Make sure your origin firewall is not rate limiting or blocking Cloudflare's published IP ranges, since all traffic arrives from them and a firewall that treats them as one noisy client can drop connections.

IIS and Windows

On IIS with Application Request Routing, the substatus codes help: 502.3 is a connection failure to the backend (often timeouts or resets), and 502.5 or 502.5 ANCM indicates an ASP.NET Core process failure. Open Event Viewer (Application log) and the ASP.NET Core module's stdout log. Check that the app pool is running and the hosting bundle is installed for the .NET version you deployed.

Fix intermittent 502s

A 502 that appears for a few seconds after every deploy usually means the backend restarts while the proxy still routes to it. Use a graceful reload (systemctl reload php8.3-fpm, nginx -s reload) or rolling deploys behind a load balancer with health checks. A 502 that arrives with traffic spikes suggests exhausted workers. A 502 on one specific URL points to a code path that crashes, so find it in the app log by timestamp.

If errors are random and rare, check for backend processes recycled by a request limit (pm.max_requests, Gunicorn max_requests), which can drop an in-flight connection when misconfigured, and for keep-alive mismatches where the proxy reuses an upstream connection the backend has already closed. Setting the backend's keep-alive timeout higher than the proxy's idle timeout avoids that race.

A decision path you can follow

  1. Request the page. Note the exact page text and headers to identify the gateway.
  2. Check the gateway's error log for the matching entry.
  3. If it says connection refused or no such file: the backend is down or addressed wrongly. Start the service, fix the socket path.
  4. If it says reset or closed prematurely: read the backend's own log and dmesg for crashes and OOM kills.
  5. If it says too big header: increase buffers.
  6. If the origin works directly but the CDN shows errors: investigate allow-listing, SSL mode and origin timeouts.
  7. If you cannot see logs: contact your host.

When to call your host

On shared and managed hosting you usually cannot restart PHP-FPM or read the proxy logs. Open a ticket if a refresh does not clear the error within a few minutes, and include the URL, UTC time, response headers and any error ID shown. Ask specifically whether the PHP handler or the account's processes crashed or hit a resource limit. If it affects all your sites at once, it is probably a server-wide problem on their side.

अगले कदम

Related tools and guides:

सामान्य प्रश्न

Is a 502 error my fault or the website's fault?

If you are a visitor, it is almost never your fault. The gateway on the site's infrastructure got a bad response from its backend. Refreshing after a minute sometimes works, because the issue may be transient.

What is the difference between 502, 503 and 504?

A 502 means the gateway got an invalid response or could not connect. A 503 means the service is unavailable, often overloaded or in maintenance. A 504 means the backend did not answer in time. Logs often distinguish them: refused or reset connections give 502, timeouts give 504.

Why do I get 502 only after a PHP update?

Updating PHP often changes the FPM service name and socket path, for example from php8.2-fpm.sock to php8.3-fpm.sock. If nginx or Apache still points at the old socket, every request fails with a 502 until the web server config is updated and reloaded.

Can a plugin or theme cause a 502?

Yes, if it makes PHP crash (segfault, memory exhaustion that kills the worker) or runs so long that a terminate timeout fires. Disable recently added plugins and check the PHP-FPM log for crashes around the time of the error.

Will increasing timeouts fix a 502?

Usually not, because 502 is about an invalid or refused connection, not slowness. Timeout settings matter for 504. Raise them only after the log shows timeouts rather than refused or reset connections.

Get notified when this guide updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.