encode/httpx · error · DecodingError
{exc}
Error message
{exc} What it means
DecodingError raised inside DeflateDecoder.decode when zlib.decompress fails on the second (raw deflate) attempt. httpx first tries zlib with default headers, then if that fails retries with -MAX_WBITS (raw deflate); a second failure bubbles up as DecodingError wrapping the underlying zlib.error. This indicates the response body declared 'deflate' Content-Encoding but is not valid zlib or raw-deflate data.
Source
Thrown at httpx/_decoders.py:76
Handle 'deflate' decoding.
See: https://stackoverflow.com/questions/1838699
"""
def __init__(self) -> None:
self.first_attempt = True
self.decompressor = zlib.decompressobj()
def decode(self, data: bytes) -> bytes:
was_first_attempt = self.first_attempt
self.first_attempt = False
try:
return self.decompressor.decompress(data)
except zlib.error as exc:
if was_first_attempt:
self.decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
return self.decode(data)
raise DecodingError(str(exc)) from exc
def flush(self) -> bytes:
try:
return self.decompressor.flush()
except zlib.error as exc: # pragma: no cover
raise DecodingError(str(exc)) from exc
class GZipDecoder(ContentDecoder):
"""
Handle 'gzip' decoding.
See: https://stackoverflow.com/questions/1838699
"""
def __init__(self) -> None:
self.decompressor = zlib.decompressobj(zlib.MAX_WBITS | 16)
View on GitHub (pinned to b5addb64f0)
Solutions
- Reproduce with curl --compressed to confirm the server is genuinely sending bad deflate; file a bug upstream.
- Strip Content-Encoding handling by reading raw bytes: iterate resp.iter_raw() instead of resp.iter_bytes().
- Disable transparent decoding by removing 'deflate' from client acceptance (set Accept-Encoding: identity).
- If the body is actually gzip, ask the server to send correct headers or pre-decode manually with gzip on resp.iter_raw().
Example fix
// before
resp = client.get(url) # server mislabels deflate
body = resp.content # DecodingError
// after
resp = client.get(url, headers={'Accept-Encoding': 'identity'})
body = resp.content # raw bytes; decode manually if needed Defensive patterns
Strategy: fallback
Validate before calling
# Before issuing, opt out of deflate if you cannot trust the server
headers = {'Accept-Encoding': 'gzip, identity'} # no deflate
resp = client.get(url, headers=headers) Try / catch
try:
body = resp.content
except httpx.DecodingError:
# server mislabeled deflate; read raw and decode manually or skip
resp = client.get(url, headers={'Accept-Encoding': 'identity'})
body = resp.content Prevention
- Pin Accept-Encoding to encodings you know the server emits correctly.
- Log Content-Encoding vs actual bytes when debugging decoding errors.
- Keep a retry path that requests identity encoding.
- Validate server behaviour with curl --compressed before coding against it.
When it happens
Trigger: Server sending 'Content-Encoding: deflate' but shipping actually-gzip or plain bytes; truncated deflate body (network drop, proxy truncation); server using an undocumented deflate variant; misconfigured origin returning an error page (HTML) with a stale deflate header.
Common situations: Upstream mislabeling encoding; CDN/proxy re-encoding body but not header; connection drops leaving a partial body; some legacy servers serving deflate of gzipped data; testing with a mock that sets the header but not the encoding.
Related errors
- Zstandard data is incomplete
- Using 'BrotliDecoder', but neither of the 'brotlicffi' or 'b
- Using 'ZStandardDecoder', ...Make sure to install httpx usin
- {error_type} '{0.status_code} {0.reason_phrase}' for url '{0
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/8863799028e3744a.json.
Report an issue: GitHub.