{"id":"075aa86b9de1d880","repo":"aio-libs/aiohttp","slug":"unknown-content-encoding-encoding","errorCode":null,"errorMessage":"unknown content encoding: {encoding}","messagePattern":"unknown content encoding: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/multipart.py","lineNumber":580,"sourceCode":"        \"\"\"\n        data = self._apply_content_transfer_decoding(data)\n        if self._needs_content_decoding():\n            async for d in self._decode_content_async(data):\n                yield d\n        else:\n            yield data\n\n    def _decode_content(self, data: bytes) -> bytes:\n        encoding = self.headers.get(CONTENT_ENCODING, \"\").lower()\n        if encoding == \"identity\":\n            return data\n        if encoding in {\"deflate\", \"gzip\"}:\n            return ZLibDecompressor(\n                encoding=encoding,\n                suppress_deflate_header=True,\n            ).decompress_sync(data, max_length=self._max_decompress_size)\n\n        raise RuntimeError(f\"unknown content encoding: {encoding}\")\n\n    async def _decode_content_async(self, data: bytes) -> AsyncIterator[bytes]:\n        encoding = self.headers.get(CONTENT_ENCODING, \"\").lower()\n        if encoding == \"identity\":\n            yield data\n        elif encoding in {\"deflate\", \"gzip\"}:\n            d = ZLibDecompressor(\n                encoding=encoding,\n                suppress_deflate_header=True,\n            )\n            yield await d.decompress(data, max_length=self._max_decompress_size)\n            while d.data_available:\n                yield await d.decompress(b\"\", max_length=self._max_decompress_size)\n        else:\n            raise RuntimeError(f\"unknown content encoding: {encoding}\")\n\n    def _decode_content_transfer(self, data: bytes) -> bytes:\n        encoding = self.headers.get(CONTENT_TRANSFER_ENCODING, \"\").lower()","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/multipart.py#L562-L598","documentation":"Raised by BodyPartReader._decode_content (the synchronous decode path used by decode()/read(decode=True)) when a part's Content-Encoding header contains a value other than 'identity', 'gzip', or 'deflate'. aiohttp's multipart decoder only knows how to decompress those three encodings via ZLibDecompressor; anything else (brotli, zstd, etc.) is unsupported.","triggerScenarios":"Receiving a multipart body part whose Content-Encoding header is set to an unsupported algorithm such as 'br' (brotli), 'zstd', 'compress', or a typo like 'gz'. Surfaced when calling `await part.read(decode=True)` or `part.decode(data)` on such a part.","commonSituations":"A CDN or proxy adds Content-Encoding: br to individual parts; a client compresses with brotli for size; version mismatch where a newer spec introduces an encoding aiohttp does not yet handle; misconfigured sender adding Content-Encoding to a multipart/form-data part (forbidden by RFC 7578 §4.8 but the non-form-data path still checks it).","solutions":["Strip or correct the Content-Encoding on the sender side so only gzip/deflate/identity is used.","If you genuinely need brotli/zstd, decompress the raw bytes yourself after `await part.read(decode=False)` using your own library.","For multipart/form-data, remove Content-Encoding from parts entirely — RFC 7578 forbids it.","Pre-filter part headers before reading if you control the writer."],"exampleFix":"// before\ndata = await part.read(decode=True)  # Content-Encoding: br -> RuntimeError\n// after\nraw = await part.read(decode=False)\ndata = brotli.decompress(raw)  # decompress manually","handlingStrategy":"validation","validationCode":"enc = part.headers.get('Content-Encoding', '').lower()\nif enc and enc not in ('identity', 'gzip', 'deflate'):\n    raise UnsupportedEncoding(f'part uses unsupported Content-Encoding: {enc}')","typeGuard":"def is_supported_content_encoding(part) -> bool:\n    enc = part.headers.get('Content-Encoding', '').lower()\n    return enc in ('', 'identity', 'gzip', 'deflate')","tryCatchPattern":"try:\n    data = await part.read(decode=True)\nexcept RuntimeError as e:\n    if 'unknown content encoding' in str(e):\n        data = await part.read(decode=False)  # consume raw\n    else:\n        raise","preventionTips":["Inspect each part's Content-Encoding before calling read(decode=True).","Strip unsupported Content-Encoding headers at a proxy before they reach aiohttp.","Document supported encodings to upstream teams to avoid brotli/zstd on multipart parts."],"tags":["multipart","content-encoding","compression","decoding"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}