Nginx Error: 'upstream sent invalid chunked response while reading upstream' — Cause and Fix
Fix nginx 'upstream sent invalid chunked response while reading upstream': the backend sends malformed Transfer-Encoding: chunked framing, causing 502.
- #nginx
- #web-server
- #troubleshooting
- #proxy
Stuck on this NGINX error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
What this error means
Nginx logs this when it is reading a proxied response that declares Transfer-Encoding: chunked but the chunk framing on the wire is malformed — a bad chunk-size line, a missing CRLF, or a truncated terminating chunk:
2026/07/12 14:22:41 [error] 2841#2841: *55210 upstream sent invalid chunked response while reading upstream, client: 203.0.113.7, server: example.com, request: "GET /api/stream HTTP/1.1", upstream: "http://10.0.3.20:8080/api/stream", host: "example.com"
Chunked transfer encoding frames a response body as a series of <hex-size>\r\n<data>\r\n blocks ending in a 0\r\n\r\n terminator. When nginx cannot parse that framing, it cannot trust the response, so it aborts the upstream read and returns 502 Bad Gateway to the client. The impact is failed responses — often on streaming or dynamically generated endpoints — that clients see as intermittent 502s despite the backend “working.”
How the server responds
- Clients get
502 Bad Gatewayon specific endpoints (often streaming or dynamically generated) while static or short responses are fine. error.logshowsupstream sent invalid chunked response while reading upstreamwith the offendingupstream:andrequest:.- The backend’s own logs show a
200and a completed response — the framing, not the status, is the problem. - Failures cluster on responses without a fixed
Content-Length(the backend chose chunked encoding). - Capturing the raw upstream response shows a broken chunk-size line, missing
\r\n, or a doubleTransfer-Encoding/Content-Lengthcombination. - The problem appears or worsens when another proxy sits between nginx and the app and re-chunks the body.
Testing the server configuration
Confirm the error and pin down the exact upstream and path from the log:
sudo grep "invalid chunked response" /var/log/nginx/error.log | tail -n 20
Ask the backend directly, bypassing nginx, and inspect the response headers to see whether it uses chunked encoding and whether it also sends Content-Length:
# Talk straight to the upstream and show headers
curl -sS -D - -o /dev/null http://10.0.3.20:8080/api/stream
# Force HTTP/1.1 and watch the framing verbosely
curl -sS -v --http1.1 http://10.0.3.20:8080/api/stream >/dev/null
Look for the red flags: both Transfer-Encoding: chunked and Content-Length present, HTTP/1.0 in the status line alongside a chunked declaration, or a body that does not end in a clean 0\r\n\r\n. Capture the raw bytes if headers look fine but framing is suspect:
# Raw capture of the upstream conversation for offline inspection
sudo tcpdump -s0 -A -i any host 10.0.3.20 and port 8080 -w /tmp/upstream.pcap
Server configuration causes
- Buggy application chunking — the backend hand-rolls chunked output (or a framework bug) and emits an incorrect chunk-size, a wrong CRLF, or an early terminator.
- Double chunking — the app sets
Transfer-Encoding: chunkedand also writes chunk framing itself, or an intermediate proxy re-chunks an already-chunked body, producing nested/invalid frames. - HTTP/1.0 backend claiming chunked — chunked encoding is an HTTP/1.1 feature; a backend speaking 1.0 that advertises
Transfer-Encoding: chunkedproduces a response nginx cannot parse under 1.0 semantics. - Conflicting
Content-LengthandTransfer-Encoding— a response carrying both headers is ambiguous; the framing nginx reads may not match either declaration. - A middlebox mangling the stream — a load balancer, WAF, or service mesh sidecar in front of the app alters the body or headers and corrupts chunk boundaries.
The fix
The correct fix is at the backend: emit valid chunked framing, or send a proper Content-Length instead of chunking. Remove any hand-written chunk framing when the framework already sets Transfer-Encoding: chunked, and never send both Transfer-Encoding and Content-Length.
On the nginx side, ensure it speaks HTTP/1.1 to the upstream so chunked responses are handled correctly, and strip conflicting hop-by-hop headers:
upstream backend {
server 10.0.3.20:8080;
keepalive 32;
}
server {
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1; # negotiate HTTP/1.1 with the backend
proxy_set_header Connection ""; # clear "close" for keepalive reuse
}
}
If the backend cannot produce valid chunked output, have it send an unchunked, buffered response with a Content-Length instead. You can also let nginx buffer the full response so it re-frames the body to the client with a length rather than passing chunks straight through:
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_buffering on; # buffer upstream response (default)
proxy_set_header Connection "";
}
Note that buffering does not repair genuinely malformed chunk bytes from the backend — it only helps when the issue is downstream re-chunking. A backend that emits corrupt frames must be fixed at the source. If an intermediate proxy is re-chunking, configure that hop to pass the body through unchanged.
Validate and reload after config changes (no restart needed for proxy directives):
sudo nginx -t && sudo systemctl reload nginx
Safe configuration practice
- The authoritative fix is at the backend; nginx directives only change how the response is negotiated and buffered, not whether the upstream’s bytes are valid.
- Never let a response carry both
Content-LengthandTransfer-Encoding: chunked— that ambiguity is a common source of this error and of request-smuggling risk. - Confirm
proxy_http_version 1.1;wherever you rely on keepalive or chunked upstreams; the default HTTP/1.0 does not support chunked request/response semantics cleanly. - When a middlebox (WAF, mesh sidecar, LB) sits in front of the app, test with and without it to find which hop mangles the framing.
- Streaming endpoints are the usual victims because they cannot know length upfront; give them extra scrutiny and consider server-sent events framing that is well tested.
- Alert on a rise in
invalid chunked responseand correlated 502s so a backend deploy that breaks framing is caught quickly via your monitoring dashboard.
Related server errors
- Nginx Error: Upstream Sent No Valid HTTP Header — a sibling upstream-protocol error where the backend’s response headers, rather than its chunk framing, are malformed.
- Nginx Error: Upstream Prematurely Closed Connection — another mid-response upstream failure that surfaces as a 502 when the backend drops the connection early.
- Nginx Error: 502 Bad Gateway — the client-facing status this error produces, with the broader set of upstream causes behind it.
See the NGINX category for more guides.
Fixed it? Get 500 NGINX & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.