{"record":{"id":"88eb119a6a61686e","repo":"aio-libs/aiohttp","slug":"the-zstd-decompression-is-not-available-please-in","errorCode":null,"errorMessage":"The zstd decompression is not available. Please install `backports.zstd` module","messagePattern":"The zstd decompression is not available\\. Please install `backports\\.zstd` module","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/compression_utils.py","lineNumber":485,"sourceCode":"        if hasattr(self._obj, \"flush\"):\n            return cast(bytes, self._obj.flush())\n        return b\"\"\n\n    @property\n    def data_available(self) -> bool:\n        return not self._obj.is_finished() and not self._last_empty\n\n\nclass ZSTDDecompressor(ConcatDecompressionHandler[\"ZstdDecompressor\"]):\n    _unlimited = ZSTD_MAX_LENGTH_UNLIMITED\n\n    def __init__(\n        self,\n        executor: Executor | None = None,\n        max_sync_chunk_size: int | None = MAX_SYNC_CHUNK_SIZE,\n    ) -> None:\n        if not HAS_ZSTD:\n            raise RuntimeError(\n                \"The zstd decompression is not available. \"\n                \"Please install `backports.zstd` module\"\n            )\n        super().__init__(executor=executor, max_sync_chunk_size=max_sync_chunk_size)\n        self._decompressor = self._new_decompressor()\n\n    def _new_decompressor(self) -> \"ZstdDecompressor\":\n        return ZstdDecompressor()\n\n    def decompress_sync(\n        self, data: bytes, max_length: int = ZLIB_MAX_LENGTH_UNLIMITED\n    ) -> bytes:\n        # zstd uses -1 for unlimited, while zlib uses 0 for unlimited\n        # Convert the zlib convention (0=unlimited) to zstd convention (-1=unlimited)\n        zstd_max_length = (\n            ZSTD_MAX_LENGTH_UNLIMITED\n            if max_length == ZLIB_MAX_LENGTH_UNLIMITED\n            else max_length","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/compression_utils.py#L467-L503","documentation":"Raised by ZSTDDecompressor.__init__ when the zstd backend is missing. On Python < 3.14 aiohttp imports backports.zstd; on 3.14+ it uses the stdlib compression.zstd module. If neither is importable (HAS_ZSTD False) and a Content-Encoding: zstd response arrives, construction of the decompressor fails immediately. The message still names backports.zstd because that is the install path for all current CPython releases.","triggerScenarios":"Server returns Content-Encoding: zstd but the optional zstd backend is not installed; Accept-Encoding was forced to include 'zstd' via custom headers; aiohttp upgraded to a version that started advertising zstd without the dep being present in the deployment image.","commonSituations":"Alpine/slim Docker images without the wheel; pinned old aiohttp in a project whose deployment env never had backports.zstd; server-side negotiation that prefers zstd before gzip.","solutions":["Install the backend: pip install backports.zstd (or run on Python 3.14+ for the stdlib module).","Remove 'zstd' from any custom Accept-Encoding header you set on requests.","If zstd is unavailable, configure the upstream to advertise gzip/identity only.","Rebuild the deployment image so the optional dep is present in the locked environment."],"exampleFix":"# shell\npip install backports.zstd\n# or, in request code, stop forcing zstd\nheaders={'Accept-Encoding': 'gzip, identity'}","handlingStrategy":"fallback","validationCode":"try:\n    from backports.zstd import ZstdDecompressor  # noqa: F401\n    HAS_ZSTD = True\nexcept ImportError:\n    try:\n        from compression.zstd import ZstdDecompressor  # noqa: F401  # py3.14+\n        HAS_ZSTD = True\n    except ImportError:\n        HAS_ZSTD = False\n\nenc = 'gzip, identity' if not HAS_ZSTD else 'gzip, zstd'\nawait session.get(url, headers={'Accept-Encoding': enc})","typeGuard":"null","tryCatchPattern":"try:\n    data = await resp.read()\nexcept RuntimeError as exc:\n    if 'zstd' in str(exc).lower():\n        raise RuntimeError('install backports.zstd or drop zstd from Accept-Encoding') from exc\n    raise","preventionTips":["Add backports.zstd (or require Python 3.14+) to deployment images.","Avoid forcing 'zstd' in custom Accept-Encoding unless the backend is present.","Document the optional decompression deps in the service's setup guide."],"tags":["decompression","dependency","zstd","runtime-error"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}