aio-libs/aiohttp · error · ContentEncodingError

Can not decode content-encoding: brotli (br). Please install

Error message

Can not decode content-encoding: brotli (br). Please install `Brotli`

What it means

ContentEncodingError raised by DeflateBuffer.__init__ when a response advertises Content-Encoding: br (brotli) but the optional Brotli dependency is not installed (HAS_BROTLI is False). aiohttp cannot decompress the body without the library.

Source

Thrown at aiohttp/http_parser.py:1138

class DeflateBuffer:
    """DeflateStream decompress stream and feed data into specified stream."""

    def __init__(
        self,
        out: StreamReader,
        encoding: str | None,
        max_decompress_size: int = DEFAULT_CHUNK_SIZE,
    ) -> None:
        self.out = out
        self.size = 0
        out.total_compressed_bytes = self.size
        self.encoding = encoding
        self._started_decoding = False

        self.decompressor: BrotliDecompressor | ZLibDecompressor | ZSTDDecompressor
        if encoding == "br":
            if not HAS_BROTLI:
                raise ContentEncodingError(
                    "Can not decode content-encoding: brotli (br). "
                    "Please install `Brotli`"
                )
            self.decompressor = BrotliDecompressor()
        elif encoding == "zstd":
            if not HAS_ZSTD:
                raise ContentEncodingError(
                    "Can not decode content-encoding: zstandard (zstd). "
                    "Please install `backports.zstd`"
                )
            self.decompressor = ZSTDDecompressor()
        else:
            self.decompressor = ZLibDecompressor(encoding=encoding)

        self._max_decompress_size = max_decompress_size

    def set_exception(
        self,

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Install Brotli: `pip install brotli` (or aiohttp[speedups] / Brotli).
  2. Restrict the Accept-Encoding you send (disable br) if you cannot install Brotli.
  3. Set auto_decompress=False on the client/server to receive raw bytes.

Example fix

// before
#   resp = await session.get(url)  # server sends br, no brotli installed

# after - option 1: install dependency
#   pip install Brotli
# option 2: disable brotli in accept-encoding
headers = {'Accept-Encoding': 'gzip, deflate'}
resp = await session.get(url, headers=headers)
# option 3: skip auto-decompress
session = aiohttp.ClientSession(auto_decompress=False)
Defensive patterns

Strategy: fallback

Validate before calling

try:
    import brotli  # noqa
    HAS_BROTLI = True
except ImportError:
    HAS_BROTLI = False

async def safe_get(session, url):
    headers = {'Accept-Encoding': 'gzip, deflate'} if not HAS_BROTLI else {}
    return await session.get(url, headers=headers)

Try / catch

from aiohttp.http_exceptions import ContentEncodingError
try:
    body = await resp.read()
except ContentEncodingError as e:
    if 'brotli' in str(e):
        # retry without br in Accept-Encoding
        ...

Prevention

When it happens

Trigger: Client sends Accept-Encoding including br, server responds with Content-Encoding: br, and the runtime lacks the Brotli package. DeflateBuffer detects encoding == 'br' and HAS_BROTLI False and raises immediately.

Common situations: Fresh aiohttp install without extras; deployment image missing brotli; CI env without optional deps; server suddenly advertising br after a config change.

Related errors


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/3dbfe324c0b041c5.json. Report an issue: GitHub.