aio-libs/aiohttp · error · RuntimeError
Using chunked encoding is forbidden for HTTP/{major}.{minor}
Error message
Using chunked encoding is forbidden for HTTP/{major}.{minor} What it means
Chunked transfer-encoding is only valid for HTTP/1.1. If you enable chunked via enable_chunked_encoding() but the client negotiated HTTP/1.0, _prepare_headers raises RuntimeError at line 392-396 rather than emitting an invalid response.
Source
Thrown at aiohttp/web_response.py:393
writer = self._payload_writer
assert writer is not None
keep_alive = self._keep_alive
if keep_alive is None:
keep_alive = request.keep_alive
self._keep_alive = keep_alive
version = request.version
headers = self._headers
if self._cookies:
populate_with_cookies(headers, self._cookies)
if self._compression:
await self._start_compression(request)
if self._chunked:
if version != HttpVersion11:
raise RuntimeError(
"Using chunked encoding is forbidden "
f"for HTTP/{request.version.major}.{request.version.minor}"
)
if not self._must_be_empty_body:
writer.enable_chunking()
headers[hdrs.TRANSFER_ENCODING] = "chunked"
elif self._length_check: # Disabled for WebSockets
writer.length = self.content_length
if writer.length is None:
if version >= HttpVersion11:
if not self._must_be_empty_body:
writer.enable_chunking()
headers[hdrs.TRANSFER_ENCODING] = "chunked"
elif not self._must_be_empty_body:
keep_alive = False
# HTTP 1.1: https://tools.ietf.org/html/rfc7230#section-3.3.2
# HTTP 1.0: https://tools.ietf.org/html/rfc1945#section-10.4View on GitHub (pinned to c0ef574e29)
Solutions
- Don't force chunked; let aiohttp auto-decide based on request version (it falls back to closing the connection for HTTP/1.0 at lines 407-408).
- Require HTTP/1.1 from clients if you must use chunked streaming.
- Remove the resp.enable_chunked_encoding() call entirely.
Example fix
# before resp = StreamResponse() resp.enable_chunked_encoding() # breaks HTTP/1.0 clients # after resp = StreamResponse() # aiohttp auto-enables chunked for 1.1, closes conn for 1.0
Defensive patterns
Strategy: validation
Validate before calling
# Don't force chunked; let aiohttp decide. If you must, gate on request version:
from aiohttp import HttpVersion11
if request.version == HttpVersion11:
resp.enable_chunked_encoding() Try / catch
try:
await resp.prepare(request)
except RuntimeError as e:
if 'chunked encoding is forbidden' in str(e):
# client is HTTP/1.0; fall back to connection-close streaming
... Prevention
- Avoid resp.enable_chunked_encoding() unless you control client protocol versions.
- Document that your endpoint requires HTTP/1.1 if you use chunked.
- Test against HTTP/1.0 clients (curl --http1.0) during development.
When it happens
Trigger: Calling resp.enable_chunked_encoding() and serving a client that sent an HTTP/1.0 request line (request.version != HttpVersion11). The version comes from the parsed request, so this depends on what the client sent, not on server config.
Common situations: Testing against an HTTP/1.0-only client or proxy (curl --http1.0, legacy tools); an upstream proxy downgrading the protocol; forcing chunked for streaming then hitting an old client.
Related errors
- Not enough data to satisfy transfer length header.
- You can't enable chunked encoding when a content length is s
- You can't set content length when chunked encoding is enable
- chunked can not be set if "Transfer-Encoding: chunked" heade
- chunked can not be set if Content-Length header is set
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/b2933ff3f45a6b85.json.
Report an issue: GitHub.