aio-libs/aiohttp · error · WebSocketError
WSCloseCode.MESSAGE_TOO_BIG
WSCloseCode.MESSAGE_TOO_BIG
Error message
Decompressed message exceeds size limit {self._max_msg_size} What it means
Raised after a compressed WebSocket message (permessage-deflate) is fully assembled and decompressed, if the decompressed size exceeds self._max_msg_size. This is the permessage-deflate equivalent of the MESSAGE_TOO_BIG guard: compressed bytes can expand greatly, so aiohttp decompresses with a max_length of max_msg_size+1 and rejects anything larger (reader_c.py:256-260).
Source
Thrown at aiohttp/_websocket/reader_c.py:257
# received.
if compressed:
if not self._decompressobj:
self._decompressobj = ZLibDecompressor(suppress_deflate_header=True)
# XXX: It's possible that the zlib backend (isal is known to
# do this, maybe others too?) will return max_length bytes,
# but internally buffer more data such that the payload is
# >max_length, so we return one extra byte and if we're able
# to do that, then the message is too big.
payload_merged = self._decompressobj.decompress_sync(
assembled_payload + WS_DEFLATE_TRAILING,
(
self._max_msg_size + 1
if self._max_msg_size
else self._max_msg_size
),
)
if self._max_msg_size and len(payload_merged) > self._max_msg_size:
raise WebSocketError(
WSCloseCode.MESSAGE_TOO_BIG,
f"Decompressed message exceeds size limit {self._max_msg_size}",
)
elif type(assembled_payload) is bytes:
payload_merged = assembled_payload
else:
payload_merged = bytes(assembled_payload)
size = len(payload_merged)
if opcode == OP_CODE_TEXT:
if self._decode_text:
try:
text = payload_merged.decode("utf-8")
except UnicodeDecodeError as exc:
raise WebSocketError(
WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message"
) from exc
View on GitHub (pinned to d9aaf697c2)
Solutions
- Raise max_msg_size on ws_connect()/WebSocketResponse() to a value that fits your largest expected message.
- Reduce message size on the sender side or stream the data in smaller application-level chunks.
- Catch WebSocketError with code MESSAGE_TOO_BIG and respond by closing with WSCloseCode.MESSAGE_TOO_BIG.
- If untrusted peers are involved, keep a strict limit to prevent a decompression resource-exhaustion (zip-bomb) attack.
Example fix
// before ws = await session.ws_connect(url) // after (allow larger decompressed payloads) ws = await session.ws_connect(url, max_msg_size=16 * 1024 * 1024)
Defensive patterns
Strategy: try-catch
Validate before calling
ws = await session.ws_connect(url, max_msg_size=16 * 1024 * 1024) # size to fit your payloads
Try / catch
from aiohttp import WSCloseCode, WebSocketError
try:
async for msg in ws:
...
except WebSocketError as exc:
if exc.code == WSCloseCode.MESSAGE_TOO_BIG:
await ws.close(code=WSCloseCode.MESSAGE_TOO_BIG) Prevention
- Set max_msg_size to the largest legitimate decompressed message you expect.
- Stream large data in smaller application-level messages instead of one big frame.
- Keep a strict limit for untrusted peers to avoid decompression bombs.
When it happens
Trigger: A remote peer negotiates permessage-deflate and sends a highly compressible payload (e.g. repetitive data) that is small on the wire but decompresses beyond max_msg_size (default 4 MB on client via ws_connect, 4 MB on server via WebSocketResponse). The check fires in _handle_frame after decompress_sync.
Common situations: Streaming large JSON/binary blobs over a compressed WS connection, a ZIP-bomb-style payload from a client, or max_msg_size lowered for memory protection while the remote sends a large compressed message.
Related errors
- Invalid window size
- Extension for deflate not supported{ext.group(1)}
- Compress wbits must between 9 and 15, zlib does not support
- WSCloseCode.MESSAGE_TOO_BIG
- WSCloseCode.PROTOCOL_ERROR
AI-assisted analysis of aio-libs/aiohttp@d9aaf697c2 (2026-08-06).
Data as JSON: /api/errors/67490cd424b5029d.
Report an issue: GitHub.