aio-libs/aiohttp · error · RuntimeError
The zstd decompression is not available. Please install `bac
Error message
The zstd decompression is not available. Please install `backports.zstd` module
What it means
Raised when constructing ZSTDDecompressor while neither the stdlib `zstandard`/`zstd` module nor the `backports.zstd` fallback is importable (HAS_ZSTD is False). It fires the first time aiohttp tries to decode a response with `Content-Encoding: zstd`. The message recommends `backports.zstd` specifically because that is what the import guard looks for.
Source
Thrown at aiohttp/compression_utils.py:394
def flush(self) -> bytes:
"""Flush the decompressor."""
if hasattr(self._obj, "flush"):
return cast(bytes, self._obj.flush())
return b""
@property
def data_available(self) -> bool:
return not self._obj.is_finished() and not self._last_empty
class ZSTDDecompressor(DecompressionBaseHandler):
def __init__(
self,
executor: Executor | None = None,
max_sync_chunk_size: int | None = MAX_SYNC_CHUNK_SIZE,
) -> None:
if not HAS_ZSTD:
raise RuntimeError(
"The zstd decompression is not available. "
"Please install `backports.zstd` module"
)
self._obj = ZstdDecompressor()
self._pending_unused_data: bytes | None = None
super().__init__(executor=executor, max_sync_chunk_size=max_sync_chunk_size)
def decompress_sync(
self, data: bytes, max_length: int = ZLIB_MAX_LENGTH_UNLIMITED
) -> bytes:
# zstd uses -1 for unlimited, while zlib uses 0 for unlimited
# Convert the zlib convention (0=unlimited) to zstd convention (-1=unlimited)
zstd_max_length = (
ZSTD_MAX_LENGTH_UNLIMITED
if max_length == ZLIB_MAX_LENGTH_UNLIMITED
else max_length
)
if self._pending_unused_data is not None:View on GitHub (pinned to c0ef574e29)
Solutions
- Install the codec: `pip install backports.zstd` (or use Python 3.14+ which ships zstdlib).
- Disable zstd negotiation by setting `Accept-Encoding: gzip, deflate, br` so the server never picks zstd.
- Verify the install in CI with `python -c "import zstandard; print(zstandard.__version__)"`.
Example fix
# before # zstd not importable -> RuntimeError on resp.text() # after # requirements.txt backports.zstd>=1.0
Defensive patterns
Strategy: validation
Validate before calling
def zstd_available() -> bool:
try:
import zstandard # noqa: F401
return True
except ImportError:
try:
import backports.zstd # noqa: F401
return True
except ImportError:
return False Try / catch
try:
body = await resp.read()
except RuntimeError as e:
if 'zstd' in str(e).lower():
# retry without 'zstd' in Accept-Encoding
...
raise Prevention
- Pin `backports.zstd` in requirements or run on Python 3.14+.
- Validate optional-dep presence in CI with `python -c "import zstandard"`.
- Strip 'zstd' from Accept-Encoding when you cannot guarantee the codec is installed.
When it happens
Trigger: Server returns `Content-Encoding: zstd` and the client environment lacks zstd support, then the response body is read and ZSTDDecompressor is instantiated.
Common situations: CDN/server upgraded to advertise zstd but the client image lacks the dep. Older Python (<3.14) without stdlib zstd and no backport installed. Cached environments where the package was removed by a cleanup step.
Related errors
- The brotli decompression is not available. Please install `B
- Can not decode content-encoding: zstandard (zstd). Please in
- Can not decode content-encoding: brotli (br). Please install
- Can not decode content-encoding: %s
- deflate
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/88eb119a6a61686e.json.
Report an issue: GitHub.