{"id":"dfa061a4b894bbda","repo":"aio-libs/aiohttp","slug":"the-brotli-decompression-is-not-available-please","errorCode":null,"errorMessage":"The brotli decompression is not available. Please install `Brotli` module","messagePattern":"The brotli decompression is not available\\. Please install `Brotli` module","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/compression_utils.py","lineNumber":350,"sourceCode":"        )\n\n    @property\n    def eof(self) -> bool:\n        return self._decompressor.eof\n\n\nclass BrotliDecompressor(DecompressionBaseHandler):\n    # Supports both 'brotlipy' and 'Brotli' packages\n    # since they share an import name. The top branches\n    # are for 'brotlipy' and bottom branches for 'Brotli'\n    def __init__(\n        self,\n        executor: Executor | None = None,\n        max_sync_chunk_size: int | None = MAX_SYNC_CHUNK_SIZE,\n    ) -> None:\n        \"\"\"Decompress data using the Brotli library.\"\"\"\n        if not HAS_BROTLI:\n            raise RuntimeError(\n                \"The brotli decompression is not available. \"\n                \"Please install `Brotli` module\"\n            )\n        self._obj = brotli.Decompressor()\n        self._last_empty = False\n        super().__init__(executor=executor, max_sync_chunk_size=max_sync_chunk_size)\n\n    def decompress_sync(\n        self, data: Buffer, max_length: int = ZLIB_MAX_LENGTH_UNLIMITED\n    ) -> bytes:\n        \"\"\"Decompress the given data.\"\"\"\n        if hasattr(self._obj, \"decompress\"):\n            if max_length == ZLIB_MAX_LENGTH_UNLIMITED:\n                result = cast(bytes, self._obj.decompress(data))\n            else:\n                result = cast(bytes, self._obj.decompress(data, max_length))\n        else:\n            if max_length == ZLIB_MAX_LENGTH_UNLIMITED:","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/compression_utils.py#L332-L368","documentation":"Raised when constructing BrotliDecompressor while the optional `Brotli` (or `brotlipy`) package is not importable - aiohttp sets HAS_BROTLI=False at import time. The decompressor is only built when a response arrives with `Content-Encoding: br`, so this RuntimeError fires at response-body read time rather than at import. aiohttp refuses to silently mis-serve compressed bytes; it asks you to install the missing codec.","triggerScenarios":"Server returns `Content-Encoding: br` (brotli) but the `Brotli` package is not installed in the environment, then `await resp.read()`/`resp.text()` triggers BrotliDecompressor construction.","commonSituations":"Fresh deploy of aiohttp without brotli extra. Slim Docker images that stripped optional deps. Server-side enablement of brotli without coordinating with the client dependency list. aiohttp[speedups]/brotli extra not in requirements.","solutions":["Install the codec: `pip install Brotli` (or add `aiohttp[brotli]` to requirements).","If you cannot install it, strip brotli from Accept-Encoding via `headers={'Accept-Encoding': 'gzip, deflate'}` so the server never returns br.","Pin Brotli in your deployment manifest so it survives image rebuilds."],"exampleFix":"# before\n# Brotli not installed -> RuntimeError on resp.read()\n# after\n# requirements.txt\nBrotli>=1.0.9","handlingStrategy":"validation","validationCode":"def brotli_available() -> bool:\n    try:\n        import brotli  # noqa: F401\n        return True\n    except ImportError:\n        return False\n\n# before issuing requests, or set Accept-Encoding to exclude 'br' if False","typeGuard":null,"tryCatchPattern":"try:\n    body = await resp.read()\nexcept RuntimeError as e:\n    if 'brotli' in str(e).lower():\n        # retry without brotli in Accept-Encoding\n        ...\n    raise","preventionTips":["Add `Brotli` (or `aiohttp[brotli]`) to your deployment requirements.","In slim images, run `pip check` in CI to confirm optional deps are present.","Restrict Accept-Encoding to codecs you can decode if you cannot guarantee the dep."],"tags":["compression","brotli","missing-dependency","response"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}