aio-libs/aiohttp · error · ValueError
compress can not be set if Content-Encoding header is set
Error message
compress can not be set if Content-Encoding header is set
What it means
Raised as ValueError in ClientRequest._update_content_encoding() when the caller passes a truthy `compress` argument while a Content-Encoding header is already set on the request. Setting both would create conflicting/duplicate compression directives, so aiohttp refuses rather than silently override the header.
Source
Thrown at aiohttp/client_reqrep.py:1210
del self.headers[hdrs.COOKIE]
for name, value in cookies.items():
# Use helper to preserve coded_value exactly as sent by server
c[name] = preserve_morsel_with_coded_value(value)
self.headers[hdrs.COOKIE] = c.output(header="", sep=";").strip()
def _update_content_encoding(
self, data: Any, compress: bool | Literal["deflate", "gzip"]
) -> None:
"""Set request content encoding."""
self.compress = None
if not data:
return
if self.headers.get(hdrs.CONTENT_ENCODING):
if compress:
raise ValueError(
"compress can not be set if Content-Encoding header is set"
)
elif compress:
if isinstance(compress, str) and compress not in {"deflate", "gzip"}:
raise ValueError(
"compress must be one of True, False, 'deflate', or 'gzip'"
)
self.compress = compress if isinstance(compress, str) else "deflate"
self.headers[hdrs.CONTENT_ENCODING] = self.compress
self.chunked = True # enable chunked, no need to deal with length
def _update_transfer_encoding(self) -> None:
"""Analyze transfer-encoding header."""
te = self.headers.get(hdrs.TRANSFER_ENCODING, "").lower()
if "chunked" in te:
if self.chunked:
raise ValueError(View on GitHub (pinned to c0ef574e29)
Solutions
- Choose one approach: either set Content-Encoding manually OR use compress=True, not both.
- If you set Content-Encoding yourself, pass compress=False (the default) and ensure the body is already encoded.
- Remove the manual Content-Encoding header before enabling compress.
Example fix
# before
await session.post(url, data=payload, compress=True,
headers={'Content-Encoding': 'gzip'})
# after - pick one
await session.post(url, data=payload, compress=True) # let aiohttp encode
# or
await session.post(url, data=gzip_bytes,
headers={'Content-Encoding': 'gzip'}) # pre-encoded Defensive patterns
Strategy: validation
Validate before calling
if compress and 'Content-Encoding' in headers:
del headers['Content-Encoding'] # or set compress=False Prevention
- Pick one compression mechanism: the compress flag OR a manual header.
- Document in helper functions which approach is used.
- Reject configs that set both at once during validation.
When it happens
Trigger: Fires at line 1208-1212 when headers already contains Content-Encoding AND the compress argument is truthy. Triggered by session.post(url, data=..., compress=True, headers={'Content-Encoding': 'gzip'}).
Common situations: Combining manual Content-Encoding headers with the compress convenience flag; copy-pasting headers from another request while also enabling compress.
Related errors
- chunked can not be set if "Transfer-Encoding: chunked" heade
- compress must be one of True, False, 'deflate', or 'gzip'
- chunked can not be set if Content-Length header is set
- Got more than {limit} bytes when reading: {line!r}.
- Invalid Content-Length header: {content_length_hdr!r}
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/bd5ca33822f6fcc7.json.
Report an issue: GitHub.