aio-libs/aiohttp · error · RuntimeError
You can't set content length when chunked encoding is enable
Error message
You can't set content length when chunked encoding is enable
What it means
Raised as RuntimeError by StreamResponse.content_length setter (aiohttp/web_response.py:213) when self._chunked is already True. This is the symmetric counterpart to error 218: once Transfer-Encoding: chunked has been enabled, you cannot also set Content-Length because HTTP forbids mixing the two framing styles.
Source
Thrown at aiohttp/web_response.py:213
self._compression = True
self._compression_force = force
self._compression_strategy = strategy
@property
def headers(self) -> "CIMultiDict[str]":
return self._headers
@property
def content_length(self) -> int | None:
# Just a placeholder for adding setter
return super().content_length
@content_length.setter
def content_length(self, value: int | None) -> None:
if value is not None:
value = int(value)
if self._chunked:
raise RuntimeError(
"You can't set content length when chunked encoding is enable"
)
self._headers[hdrs.CONTENT_LENGTH] = str(value)
else:
self._headers.pop(hdrs.CONTENT_LENGTH, None)
@property
def content_type(self) -> str:
# Just a placeholder for adding setter
return super().content_type
@content_type.setter
def content_type(self, value: str) -> None:
self.content_type # read header values if needed
self._content_type = str(value)
self._generate_content_type_header()
@propertyView on GitHub (pinned to c0ef574e29)
Solutions
- Pick one framing strategy and stick with it for the lifetime of the response.
- If you previously called enable_chunked_encoding(), do not set content_length afterwards - chunked bodies have unknown length by definition.
- Reset chunked mode (construct a new StreamResponse) if you genuinely need to switch back to a fixed length.
Example fix
// before resp = web.StreamResponse() resp.enable_chunked_encoding() resp.content_length = 100 # RuntimeError # after (option A: fixed length) resp = web.StreamResponse() resp.content_length = 100 # after (option B: chunked, no length) resp = web.StreamResponse() resp.enable_chunked_encoding()
Defensive patterns
Strategy: validation
Validate before calling
if not resp._chunked:
resp.content_length = 100 Type guard
def can_set_content_length(resp: web.StreamResponse) -> bool:
return not getattr(resp, "_chunked", False) Try / catch
try:
resp.content_length = 100
except RuntimeError:
# response is chunked; construct a new non-chunked response instead
raise Prevention
- Never set content_length after enable_chunked_encoding().
- Pick one framing strategy and stick with it for the response lifetime.
- Construct a new StreamResponse if you genuinely need to switch back.
When it happens
Trigger: Calling resp.enable_chunked_encoding() first, then assigning resp.content_length = N. Also triggered by code paths that auto-set content_length (e.g. after writing a known-size body) on a response that was already put into chunked mode.
Common situations: Middleware that forces chunked encoding on all responses conflicting with code that fixes a Content-Length; refactoring a handler from fixed-length to streaming but leaving the content_length assignment; copy-pasting code that mixed both patterns.
Related errors
- You can't enable chunked encoding when a content length is s
- Using chunked encoding is forbidden for HTTP/{major}.{minor}
- Got more than {limit} bytes when reading: {line!r}.
- Not enough data to satisfy transfer length header.
- Too many trailers received
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/b20e27e61407c392.json.
Report an issue: GitHub.