{"record":{"id":"dff2f9c814d57b10","repo":"aio-libs/aiohttp","slug":"can-not-decode-content-encoding-s","errorCode":null,"errorMessage":"Can not decode content-encoding: %s","messagePattern":"Can not decode content-encoding: (.+?)","errorType":"http","errorClass":"ContentEncodingError","httpStatus":400,"severity":"error","filePath":"aiohttp/http_parser.py","lineNumber":1200,"sourceCode":"            # RFC1950\n            # bits 0..3 = CM = 0b1000 = 8 = \"deflate\"\n            # bits 4..7 = CINFO = 1..7 = windows size.\n            if self.encoding == \"deflate\" and chunk[0] & 0xF != 8:\n                # Change the decoder to decompress incorrectly compressed data\n                # Actually we should issue a warning about non-RFC-compliant data.\n                self.decompressor = ZLibDecompressor(\n                    encoding=self.encoding, suppress_deflate_header=True\n                )\n            self._started_decoding = True\n\n        low_water = self.out._low_water\n        max_length = (\n            0 if low_water >= sys.maxsize else max(self._max_decompress_size, low_water)\n        )\n        try:\n            chunk = self.decompressor.decompress_sync(chunk, max_length=max_length)\n        except Exception:\n            raise ContentEncodingError(\n                \"Can not decode content-encoding: %s\" % self.encoding\n            )\n\n        if chunk:\n            self.out.feed_data(chunk)\n        return self.decompressor.data_available\n\n    def feed_eof(self) -> None:\n        chunk = self.decompressor.flush()\n        # This should never contain data as we defer the call until exhausting\n        # the decompression. If .flush() is returning data, this may indicate a\n        # zip bomb vulnerability as it will decompress all remaining data at once.\n        assert not chunk\n\n        if self.size > 0:\n            # decompressor is not brotli unless encoding is \"br\"\n            if self.encoding == \"deflate\" and not self.decompressor.eof:  # type: ignore[union-attr]\n                raise ContentEncodingError(\"deflate\")","sourceCodeStart":1182,"sourceCodeEnd":1218,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/http_parser.py#L1182-L1218","documentation":"Raised as ContentEncodingError when the decompressor fails on a body chunk — i.e. decompressor.decompress_sync raises any Exception. DeflateBuffer.feed_data wraps the call in try/except Exception and re-raises this generic message with the encoding name. It signals corrupt, truncated, or non-conformant compressed payload data for gzip/deflate/br/zstd.","triggerScenarios":"The body bytes fed to the decompressor do not form a valid stream for the declared Content-Encoding (gzip/deflate/br/zstd). Examples: truncated gzip stream, wrong algorithm vs header, corrupted bytes, a server sending raw deflate while declaring gzip, or a mid-stream encoding switch.","commonSituations":"Corrupt response body from a buggy server; a proxy mangling bytes; partial body due to connection drop then resumption; mislabelled Content-Encoding (server says gzip but sends raw bytes); CDN compression mismatch; downloaded file served with wrong encoding header.","solutions":["Verify the server sends a correct, complete stream for the declared Content-Encoding.","Check intermediaries (proxies, firewalls, AV) that may alter body bytes.","If you intentionally want raw bytes, disable auto-decompress: ClientSession(..., auto_decompress=False).","Re-fetch to rule out transient corruption; if reproducible, dump the raw bytes and validate with a standalone decompressor.","Confirm the Accept-Encoding you sent matches what the server actually supports."],"exampleFix":"# before (server mislabels encoding)\r\nreturn web.Response(body=gzip_data, headers={'Content-Encoding': 'deflate'})\r\n\r\n# after (correct header)\r\nreturn web.Response(body=gzip_data, headers={'Content-Encoding': 'gzip'})\r\n\r\n# or, client-side, disable auto-decompress to inspect raw bytes\r\nsession = aiohttp.ClientSession(auto_decompress=False)","handlingStrategy":"try-catch","validationCode":"import zlib, gzip\n\ndef validate_gzip_stream(raw: bytes) -> bool:\n    try:\n        zlib.decompress(raw, 16 + zlib.MAX_WBITS)\n        return True\n    except zlib.error:\n        return False","typeGuard":null,"tryCatchPattern":"from aiohttp.http_exceptions import ContentEncodingError\nimport aiohttp\n\nasync def get_with_fallback(url):\n    try:\n        async with aiohttp.ClientSession() as s:\n            async with s.get(url) as r:\n                return await r.read()\n    except ContentEncodingError:\n        # retry with auto_decompress disabled to inspect raw bytes\n        async with aiohttp.ClientSession(auto_decompress=False) as s:\n            async with s.get(url) as r:\n                return await r.read()  # caller decompresses manually","preventionTips":["Verify servers send correct, complete compressed streams.","Check intermediaries do not corrupt body bytes.","Use auto_decompress=False to debug raw bytes.","Confirm Accept-Encoding matches server capabilities."],"tags":["content-encoding","decompression","corruption","gzip","deflate"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}