aio-libs/aiohttp · error · WSHandshakeError

Extension for deflate not supported{ext.group(1)}

Error message

Extension for deflate not supported{ext.group(1)}

What it means

Raised as WSHandshakeError in ws_ext_parse() at _websocket/helpers.py:124 on the CLIENT side (isserver=False) when the server's permessage-deflate extension string contains parameters that do not match the _WS_EXT_RE grammar (server_no_context_takeover / client_no_context_takeover / server_max_window_bits / client_max_window_bits). The offending tail (ext.group(1)) is appended so you can see exactly which unsupported parameter was sent. In client.py:1151 it is re-raised as aiohttp.WSServerHandshakeError.

Source

Thrown at aiohttp/_websocket/helpers.py:124

                    notakeover = True
                # Ignore regex group 5 & 6 for client_max_window_bits
                break
            else:
                if match.group(6):
                    compress = int(match.group(6))
                    # Group5 must match if group6 matches
                    # Compress wbit 8 does not support in zlib
                    # If compress level not support,
                    # FAIL the parse progress
                    if compress > 15 or compress < 9:
                        raise WSHandshakeError("Invalid window size")
                if match.group(2):
                    notakeover = True
                # Ignore regex group 5 & 6 for client_max_window_bits
                break
        # Return Fail if client side and not match
        elif not isserver:
            raise WSHandshakeError("Extension for deflate not supported" + ext.group(1))

    return compress, notakeover


def ws_ext_gen(
    compress: int = 15, isserver: bool = False, server_notakeover: bool = False
) -> str:
    # client_notakeover=False not used for server
    # compress wbit 8 does not support in zlib
    if compress < 9 or compress > 15:
        raise ValueError(
            "Compress wbits must between 9 and 15, zlib does not support wbits=8"
        )
    enabledext = ["permessage-deflate"]
    if not isserver:
        enabledext.append("client_max_window_bits")

    if compress < 15:

View on GitHub (pinned to d9aaf697c2)

Solutions

  1. Disable client-side compression: `ws_connect(url, compress=0)` so the extension header is never parsed.
  2. Correct the server to send only RFC 7692 permessage-deflate parameters.
  3. Catch aiohttp.WSServerHandshakeError and retry without compression.

Example fix

// before
ws = await session.ws_connect(url, compress=15)

# after
ws = await session.ws_connect(url, compress=0)
Defensive patterns

Strategy: try-catch

Try / catch

try:
    ws = await session.ws_connect(url, compress=15)
except aiohttp.WSServerHandshakeError as exc:
    if 'Extension for deflate not supported' in (exc.message or ''):
        ws = await session.ws_connect(url, compress=0)
    else:
        raise

Prevention

When it happens

Trigger: Awaiting `session.ws_connect(url, compress>0)` against a server whose Sec-Websocket-Extensions header carries an unknown/ malformed permessage-deflate parameter, e.g. `permessage-deflate; foo=bar` or an extension name other than permessage-deflate that the client did not negotiate.

Common situations: Intermediary (proxy/load balancer) injecting a non-standard deflate parameter; a server implementing a draft or proprietary deflate extension; server sending an extension the client never offered.

Related errors


AI-assisted analysis of aio-libs/aiohttp@d9aaf697c2 (2026-08-06). Data as JSON: /api/errors/a9205b42f60898f4. Report an issue: GitHub.