{"record":{"id":"0a065c1d8f02ed62","repo":"aio-libs/aiohttp","slug":"using-chunked-encoding-is-forbidden-for-http-requ","errorCode":null,"errorMessage":"Using chunked encoding is forbidden for HTTP/{request.version.major}.{request.version.minor}","messagePattern":"Using chunked encoding is forbidden for HTTP/(.+?)\\.(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_response.py","lineNumber":393,"sourceCode":"        writer = self._payload_writer\n        assert writer is not None\n        keep_alive = self._keep_alive\n        if keep_alive is None:\n            keep_alive = request.keep_alive\n        self._keep_alive = keep_alive\n\n        version = request.version\n\n        headers = self._headers\n        if self._cookies:\n            populate_with_cookies(headers, self._cookies)\n\n        if self._compression:\n            await self._start_compression(request)\n\n        if self._chunked:\n            if version != HttpVersion11:\n                raise RuntimeError(\n                    \"Using chunked encoding is forbidden \"\n                    f\"for HTTP/{request.version.major}.{request.version.minor}\"\n                )\n            if not self._must_be_empty_body:\n                writer.enable_chunking()\n                headers[hdrs.TRANSFER_ENCODING] = \"chunked\"\n        elif self._length_check:  # Disabled for WebSockets\n            writer.length = self.content_length\n            if writer.length is None:\n                if version >= HttpVersion11:\n                    if not self._must_be_empty_body:\n                        writer.enable_chunking()\n                        headers[hdrs.TRANSFER_ENCODING] = \"chunked\"\n                elif not self._must_be_empty_body:\n                    keep_alive = False\n\n        # HTTP 1.1: https://tools.ietf.org/html/rfc7230#section-3.3.2\n        # HTTP 1.0: https://tools.ietf.org/html/rfc1945#section-10.4","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_response.py#L375-L411","documentation":"Raised during response preparation when chunked transfer-encoding is enabled (`_chunked = True`) but the request was made over HTTP/1.0 (or any version other than 1.1). Chunked encoding is defined only in HTTP/1.1 (RFC 9112); emitting it on a 1.0 connection would corrupt the response. aiohttp refuses rather than sending malformed data.","triggerScenarios":"Client connects via HTTP/1.0 (e.g. `curl -0`, some legacy proxies, or Python's httplib in HTTP/1.0 mode) and the handler returns a streaming Response with no Content-Length, forcing chunked encoding. Also reproducible by enabling `enable_chunking()` on a writer for a 1.0 request, or forcing `Transfer-Encoding: chunked` on a response served to a 1.0 client.","commonSituations":"A proxy/load-balancer downgrades the protocol to HTTP/1.0; curl with `--http1.0` for testing; an embedded/legacy HTTP client speaking 1.0; misconfigured reverse proxy stripping Content-Length and forcing chunked upstream while advertising 1.0 downstream.","solutions":["Return a response with an explicit Content-Length so chunking is not needed (buffer the body fully).","Ensure upstream clients/proxies speak HTTP/1.1; configure your reverse proxy to forward 1.1.","Close the connection instead of streaming: set `resp.content_length` indirectly by using a fully-buffered body so no chunking is required.","If you control the client, stop passing `-0` / `--http1.0` to curl or upgrade the client library."],"exampleFix":"// before (streaming, no content-length, HTTP/1.0 client)\nresp = StreamResponse(status=200)\nresp.content_length = None\nawait resp.prepare(request)\nawait resp.write(chunk)  # forces chunked -> RuntimeError on 1.0\n\n// after\nbody = b''.join(chunks)\nreturn Response(body=body, status=200)  # Content-Length set automatically","handlingStrategy":"validation","validationCode":"def stream_or_buffer(request, body_chunks):\n    if request.version != HttpVersion11:\n        # HTTP/1.0 cannot chunk — buffer fully\n        return Response(body=b''.join(body_chunks))\n    resp = StreamResponse()\n    resp.content_length = None\n    return resp","typeGuard":"from aiohttp.http import HttpVersion11\n\ndef supports_chunked(request) -> bool:\n    return request.version == HttpVersion11","tryCatchPattern":null,"preventionTips":["For 1.0 clients, buffer the body fully so Content-Length is set.","Ensure upstream proxies forward HTTP/1.1.","Avoid forcing Transfer-Encoding: chunked manually.","Test streaming endpoints with curl --http1.1, not --http1.0."],"tags":["aiohttp","web-response","chunked-encoding","http-1-0","streaming"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}