aio-libs/aiohttp · error · RuntimeError
You can't enable chunked encoding when a content length is…
Error message
You can't enable chunked encoding when a content length is set
What it means
StreamResponse.enable_chunked_encoding() refuses to enable chunked transfer if a Content-Length header is already present. The two are mutually exclusive under HTTP/1.1: a response carries either a fixed length or chunked framing, never both.
Solutions
- Remove the Content-Length header before enabling chunked: resp.headers.pop(hdrs.CONTENT_LENGTH, None).
- Choose one transfer mode per response — never set both.
- Avoid setting content_length on a response you intend to stream.
Example fix
# before
resp.content_length = size
resp.enable_chunked_encoding()
# after
resp.headers.pop('Content-Length', None)
resp.enable_chunked_encoding() Defensive patterns
Strategy: validation
Validate before calling
from aiohttp import hdrs
if hdrs.CONTENT_LENGTH in resp.headers:
del resp.headers[hdrs.CONTENT_LENGTH]
resp.enable_chunked_encoding() Prevention
- Decide transfer mode (fixed length vs chunked) before constructing the response.
- Never set content_length on a response you will stream.
- Remove Content-Length before enabling chunked if both ended up set.
When it happens
Trigger: Setting resp.content_length = N (or constructing Response(content_length=N)) and then calling resp.enable_chunked_encoding().
Common situations: Streaming response where length was set first by mistake; middleware adding Content-Length before the handler enables chunked; copy-paste from a fixed-length template.
Related errors
- You can't set content length when chunked encoding is enable
- chunked can not be set if Content-Length header is set
- chunked can not be set if "Transfer-Encoding: chunked"…
- Not enough data to satisfy transfer length header.
- Request has duplicate `chunked` Transfer-Encoding
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/1eb90a30bb35c5f0.
Report an issue: GitHub.
Appendix: 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 d041d4d0fd)