How To Guide

How to Fix 502 Bad Gateway Errors (Nginx, Cloudflare, Docker)

Diagnose and fix 502 Bad Gateway errors by checking upstream services, ports, proxy config, timeouts, and logs with real commands.

How to Fix 502 Bad Gateway Errors

A 502 Bad Gateway means a reverse proxy (nginx, HAProxy, Cloudflare, an AWS ALB) tried to forward your request to an upstream server and got back either nothing or an invalid response. The client did nothing wrong; the proxy could not complete the handoff. Fixing 502s is almost always about answering one question: what happened between the proxy and the backend?

What 502 actually means

RFC 9110 defines 502 as: the gateway received an invalid response from an inbound server. In practice, that covers four situations:

  • The upstream process is not running.
  • The upstream is running but not listening on the address the proxy is dialing.
  • The upstream accepted the connection but closed it or timed out before sending a full response.
  • The upstream returned bytes the proxy could not parse as HTTP (a common symptom of TLS on one side and cleartext on the other).

Work through them in that order. Do not restart nginx first, do not clear caches first, do not blame Cloudflare first.

Step 1: Confirm the upstream is running

On a systemd host:

systemctl status myapp
journalctl -u myapp -n 200 --no-pager

On Docker:

docker ps --filter name=myapp
docker logs --tail=200 myapp

If the container is restarting in a loop, that is your 502. Fix the crash before touching the proxy.

Step 2: Check it is listening on the expected port

ss -tlnp | grep -E '3000|8080|8000'
# or
netstat -tlnp | grep LISTEN

Pay attention to the bind address. A process bound to 127.0.0.1:3000 is unreachable from another container or a proxy on a different host, even though it looks fine locally. If your nginx is on the host and your app is in Docker, the app must bind 0.0.0.0 inside the container and publish the port.

Step 3: Curl the upstream directly

From the proxy machine, bypass nginx entirely:

curl -v http://127.0.0.1:3000/health
curl -v --resolve api.internal:8080:10.0.1.42 http://api.internal:8080/health

If this fails, the proxy is innocent. If it succeeds, the proxy config is the problem.

Step 4: Audit the nginx upstream and proxy_pass

Typical shape:

upstream app_backend {
    server 127.0.0.1:3000;
    keepalive 32;
}

server {
    listen 443 ssl;
    server_name api.example.com;

    location / {
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Validate and reload:

nginx -t
nginx -s reload

Common config bugs that cause 502:

  • proxy_pass https://... pointing at an HTTP-only upstream (or vice versa).
  • Trailing slash mismatch in proxy_pass producing a URI the upstream rejects.
  • SELinux on RHEL/Rocky blocking nginx from making outbound sockets. Fix with setsebool -P httpd_can_network_connect 1.

Step 5: Raise timeouts for slow endpoints

If the 502 only appears on long requests (reports, uploads, LLM streams), you are hitting timeout defaults. Set explicit values in the location or http block:

proxy_connect_timeout 10s;
proxy_send_timeout    120s;
proxy_read_timeout    120s;

The default proxy_read_timeout is 60 seconds. Anything the backend takes longer than that to answer will surface as 502 or 504 depending on when the socket dies.

Step 6: Keepalive for high-traffic upstreams

Under load, nginx can exhaust ephemeral ports opening a new TCP connection per request and start returning intermittent 502s. Add keepalive to the upstream block and set proxy_http_version 1.1 plus Connection "" in the location, as shown above.

Step 7: Read the error log

tail -f /var/log/nginx/error.log

The exact wording maps to the fix:

  • connect() failed (111: Connection refused) - upstream is down or not listening on that port.
  • upstream prematurely closed connection - the app crashed mid-request or its own timeout is shorter than nginx's.
  • no live upstreams - every server in the upstream block has been marked down; check health of each.
  • upstream sent invalid header - the app returned garbage, often because it is speaking a different protocol.

Cloudflare-specific 502s

When Cloudflare returns a 502, the issue is between Cloudflare and your origin, not between the browser and Cloudflare. Check:

  • Origin unreachable - your firewall or security group is blocking Cloudflare IPs. Allow the ranges published at cloudflare.com/ips-v4.
  • Origin timeout - Cloudflare waits 100 seconds for the origin on Free/Pro plans. Longer responses need Enterprise or a background job pattern.
  • SSL handshake failure - Full (Strict) mode requires a valid cert on the origin. Use curl -v https://origin.example.com --resolve to reproduce what Cloudflare sees.
  • Test the origin bypassing Cloudflare by editing your local hosts file or using curl --resolve. If the origin is fine directly, the fix is at Cloudflare (Page Rules, WAF, cache).

Docker networking cases

Most Docker-related 502s come down to network namespaces:

  • nginx in a container calling 127.0.0.1:3000 is calling itself, not the host and not another container. Use the other container's service name on a shared Docker network.
  • To reach a service on the host from inside a container, use host.docker.internal on Docker Desktop, or add --add-host=host.docker.internal:host-gateway on Linux.
  • If both nginx and the app are in Compose, put them on the same network and use proxy_pass http://app:3000; - Docker's embedded DNS resolves the service name.

A quick checklist

  1. Is the upstream process alive?
  2. Is it bound to the address the proxy dials?
  3. Does curl from the proxy host succeed?
  4. Does nginx -t pass and has nginx been reloaded?
  5. Are timeouts long enough for the slowest endpoint?
  6. What does the error log say, verbatim?

Answer those six in order and you will resolve almost every 502 without guesswork.

502 bad gateway nginx 502 cloudflare 502 upstream error proxy_pass proxy_read_timeout docker networking reverse proxy debugging

Explore 300+ Free Tools

Utilko has tools for developers, writers, designers, students, and everyday users — all free, all browser-based.