aio-libs/aiohttp · error · RuntimeError
The brotli decompression is not available. Please install…
Error message
The brotli decompression is not available. Please install `Brotli` module
What it means
Raised by BrotliDecompressor.__init__ when neither the brotli nor brotlicffi module could be imported at startup (HAS_BROTLI is False). aiohttp advertises 'br' in Accept-Encoding only when brotli support is detected, but if a response still arrives as Content-Encoding: br (e.g. forced by a custom headers override, a proxy, or a stale session), the decompressor is constructed and aborts immediately. Installing the optional dependency is the supported fix.
Solutions
- Install the dependency: pip install Brotli (or pip install brotlicffi on PyPy/locked-down envs).
- Install aiohttp with the relevant extra, e.g. pip install 'aiohttp[spdylite]' where applicable.
- Stop forcing Accept-Encoding: br in custom request headers when brotli is not installed.
- If you cannot add deps, configure the server/proxy to send gzip or identity instead.
Example fix
# shell # before: aiohttp installed without brotli pip install Brotli # or pin brotlicffi for environments without the C toolchain pip install brotlicffi
Defensive patterns
Strategy: fallback
Validate before calling
try:
import brotli # noqa: F401
HAS_BROTLI = True
except ImportError:
HAS_BROTLI = False
headers = {'Accept-Encoding': 'gzip, identity'} if not HAS_BROTLI else {'Accept-Encoding': 'gzip, br'}
await session.get(url, headers=headers) Type guard
null
Try / catch
try:
data = await resp.read()
except RuntimeError as exc:
if 'brotli' in str(exc).lower():
raise RuntimeError('install Brotli or drop br from Accept-Encoding') from exc
raise Prevention
- Install aiohttp with the brotli extra in deployment images.
- Do not override Accept-Encoding to include br unless brotli is installed.
- Pin the brotli dependency in requirements so CI matches production.
When it happens
Trigger: Server returns Content-Encoding: br but aiohttp was installed without the brotli extra; a reverse proxy rewrites responses to br regardless of Accept-Encoding; manual headers={'Accept-Encoding': 'br'} sent even though brotli is absent.
Common situations: Fresh pip install aiohttp without extras in a slim container; CI image missing the optional C library; pinning aiohttp to a version where the extra was renamed; brotlicffi present but import broken on the platform.
Related errors
- The zstd decompression is not available. Please install…
- Can not decode content-encoding: brotli (br). Please…
- Compressed stream has more than
- Can not decode content-encoding
- Can not decode content-encoding: zstandard (zstd). Please…
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/dfa061a4b894bbda.
Report an issue: GitHub.
Appendix: source
Thrown at aiohttp/compression_utils.py:439
)
@property
def eof(self) -> bool:
return self._decompressor.eof
class BrotliDecompressor(DecompressionBaseHandler):
# Supports both 'brotlipy' and 'Brotli' packages
# since they share an import name. The top branches
# are for 'brotlipy' and bottom branches for 'Brotli'
def __init__(
self,
executor: Executor | None = None,
max_sync_chunk_size: int | None = MAX_SYNC_CHUNK_SIZE,
) -> None:
"""Decompress data using the Brotli library."""
if not HAS_BROTLI:
raise RuntimeError(
"The brotli decompression is not available. "
"Please install `Brotli` module"
)
self._obj = brotli.Decompressor()
self._last_empty = False
super().__init__(executor=executor, max_sync_chunk_size=max_sync_chunk_size)
def decompress_sync(
self, data: Buffer, max_length: int = ZLIB_MAX_LENGTH_UNLIMITED
) -> bytes:
"""Decompress the given data."""
if hasattr(self._obj, "decompress"):
if max_length == ZLIB_MAX_LENGTH_UNLIMITED:
result = cast(bytes, self._obj.decompress(data))
else:
result = cast(bytes, self._obj.decompress(data, max_length))
else:
if max_length == ZLIB_MAX_LENGTH_UNLIMITED:View on GitHub (pinned to d041d4d0fd)