
What it means: The server started a chunked HTTP/1.1 response, then the connection closed before the final chunk arrived.
curl --http1.1Free online tool — HTTP header checker: instant results, no signup.
Requests the address and shows the status code and what the server sends back.
net::ERR_INCOMPLETE_CHUNKED_ENCODING is Chromium error -355. In net_error_list.h it reads: «The HTTP response body is transferred with Chunked-Encoding, but the terminating zero-length chunk was never sent when the connection is closed.» The server sent a status line and headers with Transfer-Encoding: chunked, started streaming the body, and the connection closed before the final 0 chunk that marks the end. The response is truncated.
This is an HTTP/1.1 error. HTTP/2 and HTTP/3 do not use chunked encoding, so the same truncation over those protocols shows up under a different code, commonly ERR_HTTP2_PROTOCOL_ERROR. Its siblings: a body shorter than its Content-Length gives ERR_CONTENT_LENGTH_MISMATCH (-354), and malformed chunks give ERR_INVALID_CHUNKED_ENCODING (-321). It is not a TLS error and not a DNS problem: the connection worked until it was closed too early.
| Browser | What you see | Most common trigger |
|---|---|---|
| Chrome, Edge | A half-rendered page, a script or stylesheet that fails in the console, or «This page isn't working» with «host unexpectedly closed the connection.» | The backend or proxy stopped mid-response: timeout, crash, full disk |
Chrome, Edge (fetch(), streaming) | The stream stops and reading the body rejects, typically with TypeError: network error | An idle timeout on a proxy or load balancer killed a long stream (SSE, LLM token streaming) |
| Firefox, Safari | A partial page or their own network-error wording; no Chrome code | The same truncated response |
Server-side truncation is by far the usual cause. The response headers are already on the wire, so the server cannot change its mind and send a 502; all it can do is close the connection. Typical reasons: an upstream timeout that fires between two reads of the body, a worker killed mid-response (OOM killer, segfault, PHP-FPM request_terminate_timeout), and nginx failing to buffer a large response to its temp directory because of wrong permissions or a full disk.
Client-side truncation also exists: the network dropped mid-download (Wi-Fi switch, VPN reconnect), or software that inspects traffic, such as a corporate proxy or an antivirus web shield, cut the response short. If only one machine sees it, start there.
Proxies are the most common place this error is born. nginx's proxy_read_timeout (default 60s) is the time allowed between two successive reads from the upstream, not for the whole response; a slow report or a model generating tokens with long pauses exceeds it, nginx closes the client connection mid-body, and the error log shows upstream timed out (110: Connection timed out) while reading upstream. HAProxy's timeout server and the AWS Application Load Balancer idle timeout (60 seconds by default) cut long streams the same way. For streaming endpoints, disable buffering and raise the read timeout only where needed:
location /api/stream {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 300s;
}An application can also turn off nginx buffering per response by sending X-Accel-Buffering: no. Behind Cloudflare, browsers usually connect over HTTP/2 or HTTP/3, so visitors see this exact code only on HTTP/1.1 connections; the truncation itself still starts at your origin or at the proxy in front of it.
curl -sS --http1.1 -o /dev/null -w '%{size_download} bytes\n' https://example.com/report
# curl: (18) transfer closed with outstanding read data remainingNote the byte count and the time it takes; a cut at a round number of seconds points to a timeout.grep -E 'while reading upstream|Permission denied|No space left' /var/log/nginx/error.log | tailupstream prematurely closed connection while reading upstream means the backend closed mid-body; upstream timed out means a timeout; a Permission denied or No space left on device line on a temp file means nginx could not buffer the response.df -h).dmesg -T | grep -i 'killed process'), PHP-FPM request_terminate_timeout and max_execution_time, and exceptions thrown after streaming has started; catch them and end the stream cleanly.proxy_read_timeout or fastcgi_read_timeout for those locations only, or send periodic data (an SSE comment line) so the connection is never idle for long.More on reading nginx logs: debugging nginx errors; on streaming responses: server-sent events.
Reload the page; a dropped Wi-Fi or mobile connection mid-download is a common one-off cause. If it keeps failing on the same page, try another network and another browser. If it fails everywhere, the site is cutting the response short and only its owner can fix it.
If it fails only on your machine, pause any VPN, proxy or antivirus web scanning and retry, and try a private window to rule out extensions. Clearing the browser cache rarely helps: a truncated response is not stored as a complete one, so the next load fetches it again anyway.
curl -sS --http1.1 -o /dev/null -w '%{http_code} %{size_download}\n' https://example.com/report
# 200 482113
curl -N --http1.1 https://example.com/api/stream # stream runs to the endA clean exit with no curl error means the final chunk arrived. Repeat for the slowest request you serve, since timeouts only show on long responses. For a quick status and header check from outside your network, use the HTTP status checker.
Long responses are the ones that hit read timeouts and fill temp buffers. A small page finishes before any limit is reached; a large export or a slow report does not.
The same truncation is reported by the protocol in use. Over HTTP/1.1 it is ERR_INCOMPLETE_CHUNKED_ENCODING; over HTTP/2 there is no chunked encoding, so Chrome reports a protocol error instead.
Very likely. A proxy or load balancer idle timeout, often 60 seconds, closes the stream mid-body. Raise the timeout for that path, disable proxy buffering, or send keep-alive comment lines.
Reproduce with curl --http1.1 and note the bytes received and the time. Then read the nginx error log at that moment: "upstream timed out" points to a timeout, "upstream prematurely closed connection" to the backend, and "No space left on device" to the temp directory.
No. TLS worked and the response started arriving; the body was cut off before its final chunk.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.