knowbase

# nginx 502 Bad Gateway: upstream returned an invalid response

nginx reached your application and did not get a usable answer back. The status says nothing about why — that is in nginx's own error log, which names the upstream, the syscall that failed and the reason, and reading it turns guesswork into one lookup.

Summary: nginx 502 Bad Gateway: upstream returned an invalid response
Error502 Bad Gateway
Applies tonginx all versions · HTTP RFC 9110
Primary causeThe upstream process is not listening
First checktail -50 /var/log/nginx/error.log | grep -i upstream
Confidencemedium2 sources, 2 primary
Verified2026-08-08fresh0d old · recheck by 2027-08-08
Domainnetworkingnginx http-502 reverse-proxy upstream timeouts deployment

## Error

502 Bad Gateway

Codes: 502

Also seen as: connect() failed (111: Connection refused) while connecting to upstream · upstream prematurely closed connection · upstream timed out (110: Connection timed out) · no live upstreams while connecting to upstream

## Problem

Requests return 502 while nginx itself is running fine. The application may be up, reachable directly on its own port, and showing nothing unusual in its logs. Restarting nginx changes nothing because nginx is not what failed — it is reporting that whatever sits behind it did.

## Root Cause6 known causes, ranked

  1. 01

    The upstream process is not listening

    primary

    Crashed, still starting, or bound to a different address. Binding to 127.0.0.1 while nginx connects to another interface — or the reverse in a container, where 127.0.0.1 is not shared — produces a refused connection.

    → how to tell: The error log says connect() failed (111: Connection refused), and ss -ltnp shows nothing listening on the expected address and port

  2. 02

    The upstream took longer than proxy_read_timeout

    primary

    nginx waits 60 seconds by default for a response and then gives up with 502. A slow query or a long export exceeds it while the application is still working normally.

    → how to tell: The error log says upstream timed out, and the elapsed request time in the access log is close to 60 seconds

  3. 03

    The upstream closed the connection mid-response

    common

    The worker was killed — OOM, a deploy, or a request timeout inside the application — after nginx had already forwarded the request. nginx receives a truncated response rather than none at all.

    → how to tell: The error log says upstream prematurely closed connection, and the application's own log shows a worker restart or OOM kill at the same timestamp

  4. 04

    Response headers exceed nginx's buffer

    common

    A large Set-Cookie or auth header can overflow proxy_buffer_size, and nginx rejects the response as invalid rather than truncating it.

    → how to tell: The error log mentions upstream sent too big header, and the failure follows requests carrying unusually large cookies or tokens

  5. 05

    The socket exists but nginx cannot use it

    common

    With a Unix socket, the nginx worker user needs permission on the socket file and every directory above it. SELinux or AppArmor can also deny the connection while permissions look correct.

    → how to tell: The error log reports permission denied on the socket path, or the denial appears in audit.log rather than in nginx's log

  6. 06

    Every server in the upstream group is marked down

    edge

    After enough failures nginx takes members out of rotation, and once the last one is out it fails immediately without attempting a connection.

    → how to tell: The error log says no live upstreams, with no connect() attempt recorded

## Solution

  1. 01Read nginx's error log. It names the upstream address, the failing syscall and the errno — which identifies the cause without needing to reproduce anything.
    $ tail -50 /var/log/nginx/error.log | grep -i upstream

    note: The distinction between 'Connection refused', 'timed out' and 'prematurely closed' maps directly onto the first three causes; they need different fixes.

  2. 02Check the upstream is listening where nginx is looking. Address mismatches are the single most common cause in containers.
    $ ss -ltnp | grep -E ':(3000|8000|8080)' ; curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/
  3. 03For a refused connection, make the bind address and the proxy_pass target agree. In a container, bind to all interfaces rather than loopback.
    javascript
    # 🔴 unreachable from another container
    app.listen(3000, "127.0.0.1");
    
    # ✅ reachable on the container network
    app.listen(3000, "0.0.0.0");
    
  4. 04For a timeout, raise the proxy timeouts only if the request is legitimately slow — otherwise fix the slow path. The default is 60 seconds.
    nginx
    location /api/export {
      proxy_pass http://app;
      proxy_connect_timeout 5s;    # reaching the upstream should be fast
      proxy_read_timeout 300s;     # this endpoint is genuinely slow
      proxy_send_timeout 300s;
    }
    

    note: Scope generous timeouts to the endpoint that needs them. Raising them globally turns every stuck request into a held worker.

  5. 05For a header-too-big error, give nginx room for the response headers.
    nginx
    proxy_buffer_size   16k;
    proxy_buffers       4 16k;
    proxy_busy_buffers_size 32k;
    
  6. 06For premature closes, look at why the worker died rather than at nginx. Check the application's memory ceiling and its own request timeout — nginx is the messenger.

verify · The request succeeds, and nginx's error log records no new upstream entries during a full traffic cycle including the slowest endpoint.

if that fails · While the root cause is being fixed, keep the site partially up by serving a cached or static response for the failing location — proxy_cache_use_stale with error and timeout lets nginx answer from cache instead of returning 502.

## Applies To

nginx
all versionsproxy_read_timeout defaults to 60s; proxy_connect_timeout to 60s.
HTTP
RFC 9110502 means a gateway received an invalid response from an upstream server.
Platforms
linux

## Not Applicable Tonear misses this page does not answer

  • 504 Gateway Timeout, which some proxies return instead of 502 for the timeout case
  • 503 Service Unavailable, typically emitted deliberately during maintenance or by rate limiting
  • 500 from the application itself, which reached nginx as a valid response and is passed through
  • 413 Request Entity Too Large, which nginx rejects before contacting the upstream at all

## Evidence2 sources

  1. 01official-docs502 Bad Gateway

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/502

    MDN Web Docs · read 2026-08-08

    supports: That 502 means a proxy received an invalid response from upstream — so the failure is always behind the proxy, which is why restarting nginx does not help.

    indicates that a server was acting as a gateway or proxy and that it received an invalid response from the upstream server

  2. https://nginx.org/en/docs/http/ngx_http_proxy_module.html

    nginx · read 2026-08-08

    supports: That the default read timeout is 60 seconds and is configurable per location, which is why slow endpoints fail at a consistent one-minute boundary.

    proxy_read_timeout 60s;

## Confidence

mediumThe meaning of 502 and the 60-second default read timeout are quoted from MDN and nginx's own module reference, and together they explain the two primary causes. Confidence is medium rather than high because it rests on two sources: the specific error-log strings used as discriminators are nginx's runtime messages rather than documented text, and the buffer sizing values are conventional starting points.

https://knowbase.sh/k/http-502-bad-gateway-nginx