aio-libs/aiohttp · error · ContentEncodingError

Can not decode content-encoding: zstandard (zstd). Please in

Error message

Can not decode content-encoding: zstandard (zstd). Please install `backports.zstd`

What it means

ContentEncodingError raised when a response advertises Content-Encoding: zstd (zstandard) but the zstandard/backports.zstd dependency is not installed (HAS_ZSTD is False). The body cannot be decompressed.

Source

Thrown at aiohttp/http_parser.py:1145

        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,
        exc: type[BaseException] | BaseException,
        exc_cause: BaseException = _EXC_SENTINEL,
    ) -> None:
        set_exception(self.out, exc, exc_cause)

    def feed_data(self, chunk: bytes) -> bool:
        """Return True if more data is available and this method should be called again with b""."""

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Install zstandard: `pip install zstandard` (or backports.zstd on supported versions).
  2. Remove zstd from your Accept-Encoding if you cannot install the dep.
  3. Use auto_decompress=False to receive raw compressed bytes.

Example fix

// before
#   server sends Content-Encoding: zstd, zstandard not installed

# after
#   pip install zstandard
# or restrict Accept-Encoding:
headers = {'Accept-Encoding': 'gzip, deflate, br'}
resp = await session.get(url, headers=headers)
Defensive patterns

Strategy: fallback

Validate before calling

try:
    import zstandard  # noqa
    HAS_ZSTD = True
except ImportError:
    HAS_ZSTD = False

async def safe_get(session, url):
    headers = {} if HAS_ZSTD else {'Accept-Encoding': 'gzip, deflate, br'}
    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 'zstd' in str(e):
        # retry without zstd
        ...

Prevention

When it happens

Trigger: Server responds with Content-Encoding: zstd and the runtime lacks the zstandard package (or backports.zstd on older Python). DeflateBuffer raises at construction time.

Common situations: New zstd adoption by a CDN/server; deploy image without zstandard; older Python needing backports.zstd; optional deps not installed.

Related errors


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