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

  1. Choose one approach: either set Content-Encoding manually OR use compress=True, not both.
  2. If you set Content-Encoding yourself, pass compress=False (the default) and ensure the body is already encoded.
  3. 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

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


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/bd5ca33822f6fcc7.json. Report an issue: GitHub.