ERR_INCOMPLETE_CHUNKED_ENCODING: Response Cut Short
ERR_INCOMPLETE_CHUNKED_ENCODING means a chunked response ended before its final chunk. Backend crash, nginx temp, or proxy? Free instant check, no sign-up.
Check your domain for this issue now
Free, no sign-up. Runs the exact check this guide describes and shows what to fix.
Problem
A page starts rendering and then stops — half the content, a broken image, an API call that returns most of its JSON and then nothing. Chrome’s console shows net::ERR_INCOMPLETE_CHUNKED_ENCODING. The server sent a response, the browser started reading it, and then the bytes ran out before the response said it was finished.
Symptoms
- The page loads partially — the top renders, the bottom is missing or cut off mid-element.
- DevTools Network tab shows the request as
(failed)or(canceled)withERR_INCOMPLETE_CHUNKED_ENCODINGin the console. - It’s intermittent: the same URL works on one load and fails on the next, or fails only for larger pages.
- The response headers include
Transfer-Encoding: chunked(notContent-Length). - Static assets are fine; the failures cluster on dynamic pages or streamed API endpoints.
What This Error Actually Means
When a server doesn’t know how long a response will be before it starts sending it — a page assembled from a database query, a streamed export, anything generated on the fly — it can’t set a Content-Length header. HTTP/1.1 solves this with chunked transfer coding (RFC 9112 §7.1): the body is sent as a series of chunks, each prefixed with its size in hex, and the whole thing is terminated by a last-chunk — a chunk of size zero (0\r\n) followed by an optional trailer and a final empty line. That zero-length chunk is the “I’m done” signal. Until it arrives, the client keeps reading.
ERR_INCOMPLETE_CHUNKED_ENCODING is Chrome telling you the connection closed before that last-chunk showed up. The server framed the response as chunked, promised more was coming, and then the socket went quiet. Chrome won’t render a body it knows is truncated — it aborts rather than show you a page that’s silently missing its tail.
The important thing to internalize: this is not a corruption error or a checksum failure. The bytes that arrived were fine. The problem is that the framing said “keep going” and the stream said “goodbye,” and those two disagreed. That disagreement almost always means something upstream died or gave up in the middle of producing the response.
Top 3 Causes
- The backend crashed or timed out mid-response. A PHP-FPM worker hits
memory_limiton a heavy page, amax_execution_timefires, an application throws after it has already flushed headers and part of the body, or the app server is killed by the OOM reaper. Headers (includingTransfer-Encoding: chunked) already went out; the terminating chunk never does. This is the classic cause behind the intermittent, size-dependent failures — the fault only triggers on the requests big or slow enough to hit the limit. - The reverse proxy can’t finish buffering the response. nginx buffers upstream responses to temporary files, and if it can’t write them — wrong ownership on its temp/cache path (the well-known
chown www-data /var/lib/nginxfix), a full disk, or an exhaustedproxy_temp_path— it abandons the response partway. The origin app is healthy; the proxy is the one dropping the tail. - An HTTP/1.0 backend speaking chunked through a proxy. Chunked coding is an HTTP/1.1 feature; it must not be used on HTTP/1.0. If your app emits chunked responses but nginx talks to it over HTTP/1.0 (the default for
proxy_pass), nginx can’t reassemble them cleanly and the browser sees a broken stream. The fix isproxy_http_version 1.1;plus clearing theConnectionheader on the upstream.
Diagnose with DechoNet
- HTTP Check fetches the URL from our servers, outside your browser and your local network. If the response completes cleanly from there but fails in your browser, the truncation is happening on your side — a local proxy, a TLS-inspection appliance, or antivirus web shielding — not at the origin.
- The same check shows you the response headers. Confirm the server is actually sending
Transfer-Encoding: chunked(and not, say, aContent-Lengththat would point you at a different error), and whether a CDN or reverse proxy is in the path. Knowing whether the framing is chunked at all is the first fork in the decision tree. - Re-run it a few times. Because the failure is intermittent and size-dependent, a single clean fetch doesn’t clear the server — but a fetch that reproduces the truncation from outside your network confirms the fault is upstream, and tells you to stop debugging your laptop.
Resolution Checklist
- Confirm it’s chunked, not fixed-length. Check the response headers for
Transfer-Encoding: chunked. If you seeContent-Lengthinstead, you’re chasing the wrong error — that’sERR_CONTENT_LENGTH_MISMATCHterritory. - Read the backend logs for the failing request. Look for OOM kills,
memory_limit/max_execution_timein PHP, worker restarts, or unhandled exceptions that fire after output started. The timestamp lines up with the truncated request. - Raise the limits that are firing. If it’s memory or execution time on large responses, bump
memory_limit/max_execution_time(PHP), or the equivalent worker timeout — or better, fix the query or view that’s generating an oversized response. - Check the proxy’s temp/cache directory. For nginx: confirm the worker user owns
proxy_temp_path(and/var/lib/nginx), that the disk isn’t full, and that buffering isn’t failing silently. The error log will name the path it couldn’t write. - Fix HTTP/1.0-to-chunked mismatches. If your app sends chunked responses, set
proxy_http_version 1.1;andproxy_set_header Connection "";so nginx speaks 1.1 upstream. - Isolate client vs. server. Fetch the URL with an external HTTP Check or
curl -vfrom another network. Reproduces externally → fix the origin/proxy. Only fails in your browser → look at local proxies, corporate MITM, or antivirus.
When to Escalate
- If the backend logs are clean and an external fetch still truncates, escalate to whoever owns the reverse proxy or CDN — the response may be dying at an edge you don’t control, and only their logs will show the aborted upstream read.
- If the failures started right after a deploy or a traffic spike, treat it as a capacity problem, not a config bug: something is now large or slow enough to cross a limit that used to have headroom. Roll back or raise the limit while you find the response that grew.
Related Tools
Related Guides
Share this guide