aio-libs/aiohttp · error · ContentLengthError
Not enough data to satisfy content length header (received {
Error message
Not enough data to satisfy content length header (received {received} of {expected} bytes). What it means
ContentLengthError raised in HttpPayloadParser.feed_eof when the connection closes while the body is being read in PARSE_LENGTH mode and fewer than Content-Length bytes arrived. The message reports received vs expected bytes.
Source
Thrown at aiohttp/http_parser.py:918
self.payload = real_payload
def pause_reading(self) -> None:
self._paused = True
def feed_eof(self) -> None:
if self._type == ParseState.PARSE_UNTIL_EOF:
self._eof_pending = True
while self._more_data_available:
if self._paused:
self._paused = False
return # Will resume via feed_data(b"") later
self._more_data_available = self.payload.feed_data(b"")
self.payload.feed_eof()
self.done = True
self._eof_pending = False
elif self._type == ParseState.PARSE_LENGTH:
received = self._length_expected - self._length
raise ContentLengthError(
f"Not enough data to satisfy content length header "
f"(received {received} of {self._length_expected} bytes)."
)
elif self._type == ParseState.PARSE_CHUNKED:
raise TransferEncodingError(
"Not enough data to satisfy transfer length header."
)
def feed_data(
self, chunk: bytes, SEP: _SEP = b"\r\n", CHUNK_EXT: bytes = b";"
) -> tuple[PayloadState, bytes]:
"""Receive a chunk of data to process.
Return:
PayloadState - The current state of payload processing.
This function may be called with empty bytes after returning
PAYLOAD_HAS_PENDING_INPUT to continue processing after a pause.
bytes - If payload is complete, this is the unconsumed bytes intended for theView on GitHub (pinned to c0ef574e29)
Solutions
- Verify the server's Content-Length matches the actual body size (capture with curl -i).
- Check for proxies/CDNs truncating large responses or applying compression that changes body size.
- Retry the request; if reproducible, report to the server owner.
- Handle ContentLengthError and fall back to a streaming/transfer-encoding read.
Defensive patterns
Strategy: try-catch
Try / catch
from aiohttp.http_exceptions import ContentLengthError
try:
body = await resp.read()
except ContentLengthError:
# truncated body — retry or stream
... Prevention
- Treat ContentLengthError as a transport-level truncation, not an app error.
- Use streaming reads to detect truncation early on large downloads.
When it happens
Trigger: Server declared Content-Length: N but the socket closed after delivering < N bytes. feed_eof() in the PARSE_LENGTH branch computes `received = _length_expected - _length` and raises ContentLengthError.
Common situations: Truncated responses from a reverse proxy that times out mid-body; upstream connection drop; Content-Length computed wrong (head vs body mismatch); keep-alive closed early; compression applied without recomputing Content-Length.
Related errors
- Not enough data to satisfy transfer length header.
- chunked can not be set if Content-Length header is set
- Got more than {limit} bytes when reading: {line!r}.
- Duplicate '{name}' header found.
- Data after `Connection: close`
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/4680424f6f4596ba.json.
Report an issue: GitHub.