encode/httpx · error · ImportError
Using 'ZStandardDecoder', ...Make sure to install httpx usin
Error message
Using 'ZStandardDecoder', ...Make sure to install httpx using `pip install httpx[zstd]`.
What it means
ImportError raised in ZStandardDecoder.__init__ when the zstandard package is not importable but a response arrives with 'Content-Encoding: zstd'. Like brotli, httpx pops 'zstd' from SUPPORTED_DECODERS at import time when the package is missing, so this is most often seen when manually constructing the decoder or when the package state is inconsistent. The fix is to install the zstd extra.
Source
Thrown at httpx/_decoders.py:172
# errors if a truncated or damaged data stream has been used.
self.decompressor.finish() # pragma: no cover
return b""
except brotli.error as exc: # pragma: no cover
raise DecodingError(str(exc)) from exc
class ZStandardDecoder(ContentDecoder):
"""
Handle 'zstd' RFC 8878 decoding.
Requires `pip install zstandard`.
Can be installed as a dependency of httpx using `pip install httpx[zstd]`.
"""
# inspired by the ZstdDecoder implementation in urllib3
def __init__(self) -> None:
if zstandard is None: # pragma: no cover
raise ImportError(
"Using 'ZStandardDecoder', ..."
"Make sure to install httpx using `pip install httpx[zstd]`."
) from None
self.decompressor = zstandard.ZstdDecompressor().decompressobj()
self.seen_data = False
def decode(self, data: bytes) -> bytes:
assert zstandard is not None
self.seen_data = True
output = io.BytesIO()
try:
output.write(self.decompressor.decompress(data))
while self.decompressor.eof and self.decompressor.unused_data:
unused_data = self.decompressor.unused_data
self.decompressor = zstandard.ZstdDecompressor().decompressobj()
output.write(self.decompressor.decompress(unused_data))
except zstandard.ZstdError as exc:View on GitHub (pinned to b5addb64f0)
Solutions
- Install the extra: `pip install httpx[zstd]`.
- Or directly: `pip install zstandard`.
- Pin in pyproject: `httpx[zstd]>=0.27`.
- Without installing, opt out: headers={'Accept-Encoding': 'gzip, deflate'} (no zstd).
Example fix
// before
pip install httpx
resp = client.get(url) # Cloudflare sends Content-Encoding: zstd
resp.content # ImportError
// after
pip install 'httpx[zstd]'
# or opt out:
resp = client.get(url, headers={'Accept-Encoding': 'gzip, deflate'}) Defensive patterns
Strategy: validation
Validate before calling
try:
import zstandard # noqa: F401
HAS_ZSTD = True
except ImportError:
HAS_ZSTD = False
headers = {'Accept-Encoding': 'gzip, deflate, zstd'} if HAS_ZSTD else {'Accept-Encoding': 'gzip, deflate'}
resp = client.get(url, headers=headers) Type guard
def supports_zstd() -> bool:
try:
import zstandard # noqa: F401
return True
except ImportError:
return False Try / catch
try:
body = resp.content
except ImportError as exc:
if 'zstd' in str(exc).lower() or 'zstandard' in str(exc).lower():
import subprocess; subprocess.check_call(['pip', 'install', 'httpx[zstd]'])
else:
raise Prevention
- Install httpx with the zstd extra: pip install 'httpx[zstd]'.
- Declare extras in pyproject/requirements.
- Match Accept-Encoding to installed codecs (Cloudflare sends zstd by default).
- Pin zstandard version to avoid wheel regressions.
When it happens
Trigger: Response with 'Content-Encoding: zstd' without zstandard installed (zstd is increasingly common via Cloudflare, Facebook, AWS); manually building ZStandardDecoder() in tests; lockfile missing the optional extra.
Common situations: Hitting endpoints fronted by Cloudflare (zstd enabled by default since 2023); fresh pip install httpx without extras; slim Docker images; requirements file that lists httpx but not the zstd extra.
Related errors
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/1b9c3951621dc23d.json.
Report an issue: GitHub.