{"id":"7bcfb15342f0363d","repo":"aio-libs/aiohttp","slug":"compress-wbits-must-between-9-and-15-zlib-does-no","errorCode":null,"errorMessage":"Compress wbits must between 9 and 15, zlib does not support wbits=8","messagePattern":"Compress wbits must between 9 and 15, zlib does not support wbits=8","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"aiohttp/_websocket/helpers.py","lineNumber":135,"sourceCode":"                        raise WSHandshakeError(\"Invalid window size\")\n                if match.group(2):\n                    notakeover = True\n                # Ignore regex group 5 & 6 for client_max_window_bits\n                break\n        # Return Fail if client side and not match\n        elif not isserver:\n            raise WSHandshakeError(\"Extension for deflate not supported\" + ext.group(1))\n\n    return compress, notakeover\n\n\ndef ws_ext_gen(\n    compress: int = 15, isserver: bool = False, server_notakeover: bool = False\n) -> str:\n    # client_notakeover=False not used for server\n    # compress wbit 8 does not support in zlib\n    if compress < 9 or compress > 15:\n        raise ValueError(\n            \"Compress wbits must between 9 and 15, zlib does not support wbits=8\"\n        )\n    enabledext = [\"permessage-deflate\"]\n    if not isserver:\n        enabledext.append(\"client_max_window_bits\")\n\n    if compress < 15:\n        enabledext.append(\"server_max_window_bits=\" + str(compress))\n    if server_notakeover:\n        enabledext.append(\"server_no_context_takeover\")\n    # if client_notakeover:\n    #     enabledext.append('client_no_context_takeover')\n    return \"; \".join(enabledext)\n","sourceCodeStart":117,"sourceCodeEnd":149,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/_websocket/helpers.py#L117-L149","documentation":"ValueError raised by ws_ext_gen() when the 'compress' (window-bits) argument is outside the inclusive range 9-15. zlib does not support wbits=8 and values above 15 exceed the deflate spec, so the generator refuses to build an invalid Sec-WebSocket-Extensions offer. Unlike errors [1]/[2] this is a programming/config error on the local side, not a peer-handshake rejection.","triggerScenarios":"Calling aiohttp.http.ws_ext_gen(compress=8) (or 7, 16, 0, negative) directly, or a code path that passes an out-of-range integer compress value into the extension-string generator. On the server, ws_ext_parse(isserver=True) clamps out-of-range client offers to 0 (so the public WebSocketResponse path normally shields you), so this is most often hit by direct ws_ext_gen callers or custom negotiation code.","commonSituations":"Custom WebSocket handshake code that forwards an unvalidated wbits value to ws_ext_gen; porting code that assumed wbits=8 was allowed; passing WebSocketResponse(compress=8) expecting it to mean 'compression level 8' (it is a window-bits value, not a level).","solutions":["Pass a compress value in 9-15, or simply use the default 15 / compress=True.","Clamp the value before generating: compress = max(9, min(15, requested)).","Do not conflate 'compress' (permessage-deflate window bits) with zlib compression level (1-9); use the correct parameter for each.","If you genuinely need no compression, pass compress=0 / compress=False rather than an out-of-range integer."],"exampleFix":"# before\nfrom aiohttp.http import ws_ext_gen\nhdr = ws_ext_gen(compress=8)  # ValueError\n\n# after\nfrom aiohttp.http import ws_ext_gen\nhdr = ws_ext_gen(compress=9)  # smallest legal window size","handlingStrategy":"validation","validationCode":"from aiohttp.http import ws_ext_gen\n\ndef safe_ws_ext_gen(compress):\n    if compress == 0:\n        return ''\n    if not (9 <= compress <= 15):\n        raise ValueError(f'compress must be 9-15, got {compress}')\n    return ws_ext_gen(compress=compress)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass compress in the 9-15 range, or use the bool/15 default.","Remember 'compress' is a window-bits value, not a zlib level (1-9).","Use compress=0/False to disable, never an out-of-range integer."],"tags":["websocket","compression","validation","deflate","server"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}