Skip to content

Websocket connect fails when a request header value is not valid UTF-8 #7600

Closed

Description

@FarhanAliRaza

Problem

_decode_asgi_headers in reflex/app.py decodes every request header name and value as UTF-8:

return {k.decode("utf-8"): v.decode("utf-8") for (k, v) in headers}

HTTP allows bytes 0x80–0xFF in field values (obs-text, RFC 9110 §5.5). These bytes are not always valid UTF-8. When the websocket handshake carries such a value, on_connect raises UnicodeDecodeError. The socket.io connect is never acknowledged, so the client cannot connect.

The client does not control every header. A proxy, a CDN or a browser extension can add one.

Reproduction

On main (d8cb464c2f), granian 2.8.3, Python 3.14:

  1. Run any app: reflex run --backend-only.
  2. Send a websocket handshake to /_event/?token=<uuid>&EIO=4&transport=websocket with the header X-Name: caf\xe9 (one raw latin-1 byte). Then send the socket.io CONNECT packet 40/_event,.

Result:

X-Name bytes Upgrade socket.io CONNECT ack
cafe 101 yes
caf\xe9 101 no

Backend log:

  File "reflex/app.py", line 2232, in on_connect
    self._static_router_data[sid] = self._build_static_router_data(sid, environ)
  File "reflex/app.py", line 2259, in _build_static_router_data
    headers = _decode_asgi_headers(asgi_scope.get("headers", []))
  File "reflex/app.py", line 2104, in _decode_asgi_headers
    return {k.decode("utf-8"): v.decode("utf-8") for (k, v) in headers}
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3: unexpected end of data

Possible fixes

  • Decode as latin-1, as Starlette does (starlette.datastructures.Headers). It never fails and is lossless. But a UTF-8 value such as café then shows as café, and the existing assertion in test_decode_asgi_headers changes.
  • Decode as UTF-8, and fall back to latin-1 only for a value that is not valid UTF-8. This keeps today's output for valid values.

Notes

#7588 changes the same function to combine repeated headers. It keeps the UTF-8 decode, so this issue applies with or without it.

Activity

  1. linear-code commented on Oct 19, 2026

    @linear-code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions