aio-libs/aiohttp · error · RuntimeError
You can't enable chunked encoding when a content length is s
Error message
You can't enable chunked encoding when a content length is set
What it means
Raised as RuntimeError by StreamResponse.enable_chunked_encoding() (aiohttp/web_response.py:177) when a Content-Length header is already present in self._headers. HTTP does not allow both Transfer-Encoding: chunked and Content-Length on the same response - they imply conflicting framing - so aiohttp refuses rather than silently emit a malformed message.
Source
Thrown at aiohttp/web_response.py:177
elif "\r" in reason or "\n" in reason:
raise ValueError("Reason cannot contain \\r or \\n")
self._reason = reason
@property
def keep_alive(self) -> bool | None:
return self._keep_alive
def force_close(self) -> None:
self._keep_alive = False
@property
def body_length(self) -> int:
return self._body_length
def enable_chunked_encoding(self) -> None:
"""Enables automatic chunked transfer encoding."""
if hdrs.CONTENT_LENGTH in self._headers:
raise RuntimeError(
"You can't enable chunked encoding when a content length is set"
)
self._chunked = True
def enable_compression(
self,
force: ContentCoding | None = None,
strategy: int | None = None,
) -> None:
"""Enables response compression encoding."""
# Don't enable compression if content is already encoded.
# This prevents double compression and provides a safe, predictable behavior
# without breaking existing code that may call enable_compression() on
# responses that already have Content-Encoding set (e.g., FileResponse
# serving pre-compressed files).
if hdrs.CONTENT_ENCODING in self._headers:
return
self._compression = TrueView on GitHub (pinned to c0ef574e29)
Solutions
- Decide on one framing: either set Content-Length for fixed-size bodies, or enable chunked for streams - not both.
- Remove Content-Length before calling enable_chunked_encoding(): resp.headers.popall('Content-Length', None).
- Avoid blanket middleware that calls enable_chunked_encoding() unconditionally; check content_length first.
Example fix
// before
resp = web.StreamResponse(headers={"Content-Length": "100"})
resp.enable_chunked_encoding() # RuntimeError
# after
resp = web.StreamResponse()
resp.enable_chunked_encoding() # no Content-Length set Defensive patterns
Strategy: validation
Validate before calling
if "Content-Length" not in resp.headers:
resp.enable_chunked_encoding() Type guard
def can_enable_chunked(resp: web.StreamResponse) -> bool:
return "Content-Length" not in resp.headers and not resp._chunked Try / catch
try:
resp.enable_chunked_encoding()
except RuntimeError:
resp.headers.popall("Content-Length", None)
resp.enable_chunked_encoding() Prevention
- Pick one framing strategy (chunked OR Content-Length), never both.
- Avoid blanket middleware that flips chunked on unconditionally.
- Remove Content-Length before calling enable_chunked_encoding().
When it happens
Trigger: Calling resp.enable_chunked_encoding() after setting Content-Length via resp.content_length = N, resp.headers['Content-Length'] = 'N', or constructing StreamResponse(headers={'Content-Length': '123'}). Triggered by both direct calls and middleware that flips chunked on for streaming bodies.
Common situations: Middleware that auto-enables chunked encoding on every response (including those with a known length); handlers that compute Content-Length then pass the response to a streaming helper; copying headers from an upstream response that already had Content-Length.
Related errors
- You can't set content length when chunked encoding is enable
- 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/1eb90a30bb35c5f0.json.
Report an issue: GitHub.