{"record":{"id":"689f3da4d91c679f","repo":"fatedier/frp","slug":"unexpected-frame-type-d-want-d-689f3d","errorCode":null,"errorMessage":"unexpected frame type %d, want %d","messagePattern":"unexpected frame type (.+?), want (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/msg/udp_binary.go","lineNumber":288,"sourceCode":"\t\tframe, err := EncodeV2MessageFrame(message)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn rw.conn.WriteFrame(frame)\n\t}\n\tbody, err := EncodeUDPPacketBinary(packet)\n\tif err != nil {\n\t\treturn err\n\t}\n\tpayload := make([]byte, 2+len(body))\n\tbinary.BigEndian.PutUint16(payload[:2], V2TypeUDPPacketBinary)\n\tcopy(payload[2:], body)\n\treturn rw.conn.WriteFrame(&wire.Frame{Type: wire.FrameTypeMessage, Payload: payload})\n}\n\nfunc decodeV2BinaryUDPPacketFrame(frame *wire.Frame) (*UDPPacket, error) {\n\tif frame.Type != wire.FrameTypeMessage {\n\t\treturn nil, fmt.Errorf(\"unexpected frame type %d, want %d\", frame.Type, wire.FrameTypeMessage)\n\t}\n\tif len(frame.Payload) < 2 {\n\t\treturn nil, fmt.Errorf(\"message frame payload too short\")\n\t}\n\tif binary.BigEndian.Uint16(frame.Payload[:2]) != V2TypeUDPPacketBinary {\n\t\treturn nil, unexpectedV2UDPPacketType(frame)\n\t}\n\treturn DecodeUDPPacketBinary(frame.Payload[2:])\n}\n\nfunc isV2MessageType(frame *wire.Frame, typeID uint16) bool {\n\treturn frame.Type == wire.FrameTypeMessage && len(frame.Payload) >= 2 && binary.BigEndian.Uint16(frame.Payload[:2]) == typeID\n}\n\nfunc unexpectedV2UDPPacketType(frame *wire.Frame) error {\n\tif frame.Type != wire.FrameTypeMessage {\n\t\treturn fmt.Errorf(\"unexpected frame type %d, want %d\", frame.Type, wire.FrameTypeMessage)\n\t}","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/msg/udp_binary.go#L270-L306","documentation":"decodeV2BinaryUDPPacketFrame received a wire frame whose type is not FrameTypeMessage while decoding a binary UDP packet. Under the v2 wire protocol each UDP packet must ride in a message frame; other frame types (e.g. stream/control frames) indicate the stream is being misinterpreted. This is an internal consistency check after the frame was already routed here by type ID.","triggerScenarios":"ReadMsg()/decodeV2BinaryUDPPacketFrame processes a frame with frame.Type != FrameTypeMessage — typically after stream desynchronization, or when a raw connection is fed into V2BinaryUDPPacketReadWriter without the v2 wire framing.","commonSituations":"Wrapping the wrong io.ReadWriter (a plain TCP conn expected to speak v2 wire frames); debugging harnesses replaying captured bytes; stream corruption from an intermediary.","solutions":["Verify the io.ReadWriter passed to NewV2BinaryUDPPacketReadWriter is a connection that actually carries v2 wire frames (use wire.NewConn framing).","Use NewUDPPacketReadWriter to construct the read writer — it selects the correct codec from the negotiated protocol strings.","Treat the error as fatal for the connection and reconnect."],"exampleFix":"// before\nrw := msg.NewV2BinaryUDPPacketReadWriter(rawConn) // rawConn lacks v2 wire framing\n\n// after\nrw, err := msg.NewUDPPacketReadWriter(rawConn, wire.ProtocolV2, wire.UDPPacketCodecBinary)","handlingStrategy":"validation","validationCode":"// construct via the factory, never by hand\nrw, err := msg.NewUDPPacketReadWriter(conn, wireProtocol, udpPacketCodec)\nif err != nil {\n\treturn err\n}","typeGuard":null,"tryCatchPattern":"if _, err := rw.ReadMsg(); err != nil {\n\tif strings.Contains(err.Error(), \"unexpected frame type\") {\n\t\tconn.Close() // wrong framing layer; reconnect\n\t}\n}","preventionTips":["Only pass v2-wire-framed connections to V2 message components.","Use NewUDPPacketReadWriter so protocol/codec selection is centralized."],"tags":["protocol","framing","udp","frp"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}