aio-libs/aiohttp · error · ValueError
chunked can not be set if Content-Length header is set
Error message
chunked can not be set if Content-Length header is set
What it means
Raised as ValueError in _update_transfer_encoding() when self.chunked is True and the request also carries a Content-Length header. HTTP semantics forbid advertising both a fixed length and chunked transfer encoding on the same request; the two framing mechanisms are mutually exclusive.
Source
Thrown at aiohttp/client_reqrep.py:1235
)
self.compress = compress if isinstance(compress, str) else "deflate"
self.headers[hdrs.CONTENT_ENCODING] = self.compress
self.chunked = True # enable chunked, no need to deal with length
def _update_transfer_encoding(self) -> None:
"""Analyze transfer-encoding header."""
te = self.headers.get(hdrs.TRANSFER_ENCODING, "").lower()
if "chunked" in te:
if self.chunked:
raise ValueError(
"chunked can not be set "
'if "Transfer-Encoding: chunked" header is set'
)
elif self.chunked:
if hdrs.CONTENT_LENGTH in self.headers:
raise ValueError(
"chunked can not be set if Content-Length header is set"
)
self.headers[hdrs.TRANSFER_ENCODING] = "chunked"
def _update_body_from_data(self, body: Any) -> None:
"""Update request body from data."""
if body is None:
self._body = self._EMPTY_BODY
# Set Content-Length to 0 when body is None for methods that expect a body
if (
self.method not in self.GET_METHODS
and not self.chunked
and hdrs.CONTENT_LENGTH not in self.headers
):
self.headers[hdrs.CONTENT_LENGTH] = "0"
return
View on GitHub (pinned to c0ef574e29)
Solutions
- Do not set Content-Length when using chunked=True or streaming bodies.
- Let aiohttp compute framing: it picks Content-Length for fixed bytes and chunked for streams.
- Remove any manually-set Content-Length header before sending a streaming body.
- Buffer the body into bytes first if you need a fixed Content-Length.
Example fix
# before
await session.post(url, data=async_generator(),
chunked=True,
headers={'Content-Length': '1024'})
# after - let aiohttp decide framing
await session.post(url, data=async_generator(), chunked=True)
# or buffer first
body = b''.join([chunk async for chunk in gen])
await session.post(url, data=body) # Content-Length auto-set Defensive patterns
Strategy: validation
Validate before calling
if chunked and 'Content-Length' in headers:
del headers['Content-Length'] # chunked and length are mutually exclusive Prevention
- Never set Content-Length on streaming/chunked bodies.
- Buffer the body into bytes if you need a fixed length.
- Let aiohttp choose framing automatically when possible.
When it happens
Trigger: Fires at line 1233-1237 when chunked flag is True, no Transfer-Encoding header is set, but CONTENT_LENGTH is present in headers. Triggered by passing chunked=True together with a Content-Length header, or when a body sets Content-Length and chunked is forced on.
Common situations: Forcing chunked=True for a streaming body while a middleware also sets Content-Length; manually setting Content-Length on a request with a generator/async-generator body (which aiohttp auto-chunks).
Related errors
- chunked can not be set if "Transfer-Encoding: chunked" heade
- compress can not be set if Content-Encoding header is set
- Transfer-Encoding can't be present with Content-Length
- Content length is set automatically
- Invalid Content-Length header: {content_length_hdr!r}
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/199e512a479f3673.json.
Report an issue: GitHub.