encode/httpx · error · ImportError

Using 'BrotliDecoder', but neither of the 'brotlicffi' or 'b

Error message

Using 'BrotliDecoder', but neither of the 'brotlicffi' or 'brotli' packages have been installed. Make sure to install httpx using `pip install httpx[brotli]`.

What it means

ImportError raised in BrotliDecoder.__init__ when neither the brotli nor brotlicffi package is importable but a response arrives with 'Content-Encoding: br'. httpx lazily registers the 'br' decoder only if a brotli library is present at import time (SUPPORTED_DECODERS.pop('br') otherwise), so this firing means the library became available at decoder-construction time inconsistently, or the decoder was constructed manually. The fix is to install the optional brotli extra.

Source

Thrown at httpx/_decoders.py:120

        try:
            return self.decompressor.flush()
        except zlib.error as exc:  # pragma: no cover
            raise DecodingError(str(exc)) from exc


class BrotliDecoder(ContentDecoder):
    """
    Handle 'brotli' decoding.

    Requires `pip install brotlipy`. See: https://brotlipy.readthedocs.io/
        or   `pip install brotli`. See https://github.com/google/brotli
    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) -> None:
        if brotli is None:  # pragma: no cover
            raise ImportError(
                "Using 'BrotliDecoder', but neither of the 'brotlicffi' or 'brotli' "
                "packages have been installed. "
                "Make sure to install httpx using `pip install httpx[brotli]`."
            ) from None

        self.decompressor = brotli.Decompressor()
        self.seen_data = False
        self._decompress: typing.Callable[[bytes], bytes]
        if hasattr(self.decompressor, "decompress"):
            # The 'brotlicffi' package.
            self._decompress = self.decompressor.decompress  # pragma: no cover
        else:
            # The 'brotli' package.
            self._decompress = self.decompressor.process  # pragma: no cover

    def decode(self, data: bytes) -> bytes:
        if not data:
            return b""

View on GitHub (pinned to b5addb64f0)

Solutions

  1. Install the extra: `pip install httpx[brotli]` (pulls brotli on CPython, brotlicffi on PyPy).
  2. Alternatively `pip install brotli` (or brotlicffi on PyPy).
  3. Pin the extra in requirements.txt/pyproject: `httpx[brotli]>=0.27`.
  4. If you cannot install, avoid br by sending Accept-Encoding: gzip, deflate (no br) so the server won't brotli-encode.

Example fix

// before
pip install httpx
resp = client.get(url)  # server sends Content-Encoding: br
resp.content  # ImportError
// after
pip install 'httpx[brotli]'
# or, without installing, opt out of br:
resp = client.get(url, headers={'Accept-Encoding': 'gzip, deflate'})
Defensive patterns

Strategy: validation

Validate before calling

# Detect missing brotli before sending
try:
    import brotli  # noqa: F401
    HAS_BROTLI = True
except ImportError:
    HAS_BROTLI = False

headers = {'Accept-Encoding': 'gzip, deflate, br'} if HAS_BROTLI else {'Accept-Encoding': 'gzip, deflate'}
resp = client.get(url, headers=headers)

Type guard

def supports_brotli() -> bool:
    try:
        import brotli  # noqa: F401
        return True
    except ImportError:
        try:
            import brotlicffi  # noqa: F401
            return True
        except ImportError:
            return False

Try / catch

try:
    body = resp.content
except ImportError as exc:
    if 'brotli' in str(exc).lower():
        import subprocess; subprocess.check_call(['pip', 'install', 'httpx[brotli]'])
        # then re-request
    else:
        raise

Prevention

When it happens

Trigger: Response with 'Content-Encoding: br' when httpx was installed without the brotli extra; manually instantiating BrotliDecoder() in tests; environment where brotli was uninstalled/locked out after httpx imported; CI image missing the C brotli library.

Common situations: Fresh pip install httpx without extras hitting a brotli-compressed CDN (Cloudflare, Google often send br); deploying to a slim Docker image; upgrading Python without reinstalling binary wheels; dev-vs-prod dependency mismatch (extras only in requirements-dev).

Related errors


AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04). Data as JSON: /data/errors/b971cf9aa797d96b.json. Report an issue: GitHub.