aio-libs/aiohttp · error · WebSocketError
1007
1007
Error message
Invalid UTF-8 text message
What it means
A TEXT (opcode 0x01) frame's assembled payload is not valid UTF-8. RFC 6455 §6.1 requires the connection to fail with code 1007 when a text payload is non-UTF-8; aiohttp catches `UnicodeDecodeError` and closes with 1007.
Solutions
- Fix the peer to send UTF-8-encoded text, or use BINARY frames for non-text data.
- Handle `WSMsgType.ERROR` and reconnect — the connection is already failed with 1007.
Defensive patterns
Strategy: type-guard
Type guard
def is_error(msg) -> bool:
return msg.type == aiohttp.WSMsgType.ERROR Try / catch
msg = await ws.receive()
if msg.type == aiohttp.WSMsgType.ERROR:
exc = msg.data # a WebSocketError
close_code = exc.code # 1002/1007/1009/...
log.warning("ws protocol error %s: %s", close_code, exc) Prevention
- If you generate text frames, always encode with `.encode('utf-8')`.
- Use BINARY (`send_bytes`) for anything that is not definitely UTF-8 text.
When it happens
Trigger: Peer sends a TEXT frame containing bytes that are not valid UTF-8 (e.g. raw Latin-1, a multibyte sequence split incorrectly across fragments after assembly, or binary mislabeled as text).
Common situations: Peer encodes strings in a non-UTF-8 encoding; a proxy corrupts/reassembles fragments; binary data accidentally sent as a TEXT frame.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/d717194b31f376eb.
Report an issue: GitHub.
Appendix: source
Thrown at aiohttp/_websocket/reader_c.py:281
"Compressed message has too many deflate members",
) from exc
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
# XXX: The Text and Binary messages here can be a performance
# bottleneck, so we use tuple.__new__ to improve performance.
# This is not type safe, but many tests should fail in
# test_client_ws_functional.py if this is wrong.
msg = TUPLE_NEW(WSMessageText, (text, size, "", WS_MSG_TYPE_TEXT))
else:
# Return raw bytes for TEXT messages when decode_text=False
msg = TUPLE_NEW(
WSMessageTextBytes, (payload_merged, size, "", WS_MSG_TYPE_TEXT)
)
else:
msg = TUPLE_NEW(
WSMessageBinary, (payload_merged, size, "", WS_MSG_TYPE_BINARY)
)
View on GitHub (pinned to d041d4d0fd)