aio-libs/aiohttp · error · WebSocketError

1007

1007

Error message

Invalid UTF-8 text message

What it means

WebSocketError (1007 INVALID_TEXT) raised in _handle_frame when a TEXT message payload fails to decode as UTF-8 (decode_text is True). RFC 6455 requires TEXT frames to be valid UTF-8; aiohttp validates this and rejects invalid payloads. Surfaced as msg.type == WSMsgType.ERROR with msg.data.code == 1007.

Source

Thrown at aiohttp/_websocket/reader_c.py:272

                    ),
                )
                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 c0ef574e29)

Solutions

  1. Ensure the sender only sends valid UTF-8 in TEXT frames; use BINARY frames (send_bytes) for non-text payloads.
  2. If you can tolerate raw bytes, construct the server/client with decode_text=False so TEXT payloads are returned as bytes and 1007 is not raised for them.
  3. Handle msg.type == WSMsgType.ERROR / code 1007 in the receive loop and close/reconnect.
  4. On the sender, encode explicitly: payload.encode('utf-8') before framing.

Example fix

# before
ws = WebSocketResponse(decode_text=True)  # invalid UTF-8 TEXT -> 1007

# after (option A: accept raw bytes)
ws = WebSocketResponse(decode_text=False)
# option B: peer must send BINARY for non-utf8 data: await ws.send_bytes(data)
Defensive patterns

Strategy: type-guard

Validate before calling

# if non-UTF-8 TEXT is expected, receive raw bytes instead of decoding
ws = WebSocketResponse(decode_text=False)  # server side
# ws = await session.ws_connect(url, decode_text=False)  # client side (if supported)

Type guard

from aiohttp import WSMsgType

def is_invalid_text(msg) -> bool:
    return msg.type is WSMsgType.ERROR and getattr(msg.data, 'code', None) == 1007

Try / catch

msg = await ws.receive()
if msg.type is aiohttp.WSMsgType.ERROR and msg.data.code == 1007:
    log.warning('peer sent invalid UTF-8 TEXT frame')
    await ws.close()

Prevention

When it happens

Trigger: A frame with opcode 0x1 (TEXT) whose assembled payload contains invalid UTF-8 byte sequences, decoded at reader_c.py:270. Triggered by a peer that sends binary data mislabelled as a TEXT frame, or a partial UTF-8 sequence split across fragments that was reassembled incorrectly by the sender.

Common situations: A peer encoding text in latin-1/GBK/Shift-JIS but sending as TEXT; binary data accidentally sent via send_str() on the peer; a fragmenting sender that splits a multi-byte UTF-8 character incorrectly; legacy/buggy clients.

Related errors


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