aio-libs/aiohttp · error · RuntimeError

unknown content transfer encoding: {encoding}

Error message

unknown content transfer encoding: {encoding}

What it means

Raised by BodyPartReader._decode_content_transfer when a part's Content-Transfer-Encoding header is not one of the recognized values (base64, quoted-printable, binary, 8bit, 7bit). This method runs whenever a part has a Content-Transfer-Encoding header and the bytes need to be decoded.

Source

Thrown at aiohttp/multipart.py:607

                suppress_deflate_header=True,
            )
            yield await d.decompress(data, max_length=self._max_decompress_size)
            while d.data_available:
                yield await d.decompress(b"", max_length=self._max_decompress_size)
        else:
            raise RuntimeError(f"unknown content encoding: {encoding}")

    def _decode_content_transfer(self, data: bytes) -> bytes:
        encoding = self.headers.get(CONTENT_TRANSFER_ENCODING, "").lower()

        if encoding == "base64":
            return base64.b64decode(data)
        elif encoding == "quoted-printable":
            return binascii.a2b_qp(data)
        elif encoding in ("binary", "8bit", "7bit"):
            return data
        else:
            raise RuntimeError(f"unknown content transfer encoding: {encoding}")

    def get_charset(self, default: str) -> str:
        """Returns charset parameter from Content-Type header or default."""
        ctype = self.headers.get(CONTENT_TYPE, "")
        mimetype = parse_mimetype(ctype)
        return mimetype.parameters.get("charset", self._default_charset or default)

    @reify
    def name(self) -> str | None:
        """Returns name specified in Content-Disposition header.

        If the header is missing or malformed, returns None.
        """
        _, params = parse_content_disposition(self.headers.get(CONTENT_DISPOSITION))
        return content_disposition_filename(params, "name")

    @reify
    def filename(self) -> str | None:

View on GitHub (pinned to c0ef574e29)

Solutions

  1. Correct or remove the Content-Transfer-Encoding header on the sender so it is one of base64/quoted-printable/binary/8bit/7bit.
  2. If you must handle a custom encoding, read raw bytes with `await part.read(decode=False)` (note: this still calls transfer decoding — delete the header from part.headers first), then decode manually.
  3. Pre-validate part.headers before consuming the part.

Example fix

// before
data = await part.read(decode=True)  # Content-Transfer-Encoding: uuencode
// after
del part.headers['Content-Transfer-Encoding']
raw = await part.read(decode=False)
data = uu_decode(raw)
Defensive patterns

Strategy: validation

Validate before calling

cte = part.headers.get('Content-Transfer-Encoding', '').lower()
if cte and cte not in ('base64', 'quoted-printable', 'binary', '8bit', '7bit'):
    raise UnsupportedEncoding(f'unsupported CTE: {cte}')

Type guard

def is_supported_cte(part) -> bool:
    cte = part.headers.get('Content-Transfer-Encoding', '').lower()
    return cte in ('', 'base64', 'quoted-printable', 'binary', '8bit', '7bit')

Try / catch

try:
    data = await part.read(decode=True)
except RuntimeError as e:
    if 'unknown content transfer encoding' in str(e):
        del part.headers['Content-Transfer-Encoding']
        data = await part.read(decode=False)
    else:
        raise

Prevention

When it happens

Trigger: A received multipart part carries a Content-Transfer-Encoding header with an unrecognized token (e.g. 'uuencode', 'x-gzip', 'base-64' typo, or any custom value). Surfaced during `await part.read(decode=True)` / `part.decode(data)` because _apply_content_transfer_decoding is always applied when the header is present.

Common situations: Mail-style MIME parts forwarded into HTTP; legacy clients sending non-standard transfer encodings; typo in the header value; a gateway adding an encoding aiohttp does not implement.

Related errors


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