aio-libs/aiohttp · error · ContentEncodingError
Can not decode content-encoding: %s
Error message
Can not decode content-encoding: %s
What it means
Generic ContentEncodingError raised when the underlying decompressor (zlib/brotli/zstd) raises during decompress_sync — i.e. the compressed body is corrupt, truncated, or uses an unexpected format. The encoding name is interpolated into the message.
Source
Thrown at aiohttp/http_parser.py:1189
# RFC1950
# bits 0..3 = CM = 0b1000 = 8 = "deflate"
# bits 4..7 = CINFO = 1..7 = windows size.
if self.encoding == "deflate" and chunk[0] & 0xF != 8:
# Change the decoder to decompress incorrectly compressed data
# Actually we should issue a warning about non-RFC-compliant data.
self.decompressor = ZLibDecompressor(
encoding=self.encoding, suppress_deflate_header=True
)
self._started_decoding = True
low_water = self.out._low_water
max_length = (
0 if low_water >= sys.maxsize else max(self._max_decompress_size, low_water)
)
try:
chunk = self.decompressor.decompress_sync(chunk, max_length=max_length)
except Exception:
raise ContentEncodingError(
"Can not decode content-encoding: %s" % self.encoding
)
if chunk:
self.out.feed_data(chunk)
return self.decompressor.data_available
def feed_eof(self) -> None:
chunk = self.decompressor.flush()
# This should never contain data as we defer the call until exhausting
# the decompression. If .flush() is returning data, this may indicate a
# zip bomb vulnerability as it will decompress all remaining data at once.
assert not chunk
if self.size > 0:
# decompressor is not brotli unless encoding is "br"
if self.encoding == "deflate" and not self.decompressor.eof: # type: ignore[union-attr]
raise ContentEncodingError("deflate")View on GitHub (pinned to c0ef574e29)
Solutions
- Verify the body is actually encoded as advertised (curl --compressed -o /tmp/x and inspect).
- Check for a proxy/CDN re-compressing or stripping encoding.
- Retry; if stable, report to the upstream.
- As a workaround, request no compression (Accept-Encoding: identity) or set auto_decompress=False.
Example fix
// before
# body = await resp.read() # zlib.error on corrupt gzip
# after - request identity or stream raw
headers = {'Accept-Encoding': 'identity'}
resp = await session.get(url, headers=headers)
# or disable auto-decompress and handle manually
session = aiohttp.ClientSession(auto_decompress=False) Defensive patterns
Strategy: fallback
Try / catch
from aiohttp.http_exceptions import ContentEncodingError
try:
body = await resp.read()
except ContentEncodingError:
# retry without compression
async with session.get(url, headers={'Accept-Encoding': 'identity'}) as r:
body = await r.read() Prevention
- Validate Content-Encoding matches the actual bytes.
- Handle decompression errors as transport failures with retry.
When it happens
Trigger: DeflateBuffer.feed_data calls self.decompressor.decompress_sync(chunk) which raises (zlib.error, brotli error, zstd error); the exception is caught and re-raised as ContentEncodingError with the encoding. Happens on corrupt gzip/deflate/br/zstd payloads.
Common situations: Corrupt downloads; compression applied twice; Content-Encoding mismatch (server says gzip but sends raw); truncated compressed stream; intermediary altering the body.
Related errors
- Can not decode content-encoding: brotli (br). Please install
- Can not decode content-encoding: zstandard (zstd). Please in
- deflate
- compress can not be set if Content-Encoding header is set
- compress must be one of True, False, 'deflate', or 'gzip'
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/dff2f9c814d57b10.json.
Report an issue: GitHub.