AlexxIT/go2rtc · error
unsupported frame type
Error message
unsupported frame type: %d
What it means
The websocket client reader only accepts binary frames (opcode 0x2). Any other frame type — text (0x1), ping (0x9), pong (0xA), close (0x8), or continuation (0x0) — results in this error and aborts the read. The library is intentionally minimal and assumes the peer sends binary-only messages.
Solutions
- Ensure the peer sends binary frames (send Blob/ArrayBuffer in JS; TextMessage→BinaryMessage in Go clients).
- If the peer must send text, change this client to also accept TextMessage in the switch (rebuild the library).
- Handle control frames (ping/close) by responding before data frames reach this reader, or strip them with an intermediary.
- If the server speaks JSON, marshal your structs to bytes and send as binary on both ends.
Example fix
// before
switch frameType {
case BinaryMessage:
default:
return 0, fmt.Errorf("unsupported frame type: %d", frameType)
}
// after
switch frameType {
case BinaryMessage, TextMessage:
case PingMessage:
writePong(w.conn)
return 0, nil
default:
return 0, fmt.Errorf("unsupported frame type: %d", frameType)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Negotiate binary-only subprotocol or verify peer frame usage before streaming
if !peerSupportsBinaryFrames(serverURL) {
return errors.New("peer sends non-binary frames; unsupported by client")
} Type guard
func isBinaryOpcode(b byte) bool { return b&0xF == 0x2 } Try / catch
n, err := wsConn.Read(buf)
if err != nil {
var frameErr unsupportedFrameError
if errors.As(err, &frameErr) {
return handleNonBinaryFrame(frameErr.FrameType)
}
return err
} Prevention
- Always send binary frames from the peer (Blob/ArrayBuffer, BinaryMessage)
- Handle ping/pong/close frames at a layer below this reader
- Agree on binary framing in the protocol before deploying
- Audit intermediaries that may inject control frames
When it happens
Trigger: Calling Read on a websocket.Conn when the remote peer sends a text frame, or when a ping/pong/close control frame arrives mid-stream; the frame type is computed as byte&0xF and anything other than BinaryMessage errors.
Common situations: Talking to a server that defaults to JSON text frames; proxies/intermediaries injecting ping frames; misconfigured client that upgrades with a text-oriented subprotocol; library version mismatch where the peer protocol changed.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/6beb5594f9d661eb.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/tcp/websocket/client.go:39
}
const finalBit = 0x80
const maskBit = 0x80
func (w *Client) Read(b []byte) (n int, err error) {
if w.remain == 0 {
b2 := make([]byte, 2)
if _, err = io.ReadFull(w.conn, b2); err != nil {
return 0, err
}
frameType := b2[0] & 0xF
w.remain = int(b2[1] & 0x7F)
switch frameType {
case BinaryMessage:
default:
return 0, fmt.Errorf("unsupported frame type: %d", frameType)
}
switch w.remain {
case 126:
if _, err = io.ReadFull(w.conn, b2); err != nil {
return 0, err
}
w.remain = int(binary.BigEndian.Uint16(b2))
case 127:
b8 := make([]byte, 8)
if _, err = io.ReadFull(w.conn, b8); err != nil {
return 0, err
}
w.remain = int(binary.BigEndian.Uint64(b8))
}
}
if w.remain > len(b) {View on GitHub (pinned to c245815e75)