{"record":{"id":"eae6d0cb6c33a1ef","repo":"fatedier/frp","slug":"unsupported-frame-flags-d","errorCode":null,"errorMessage":"unsupported frame flags: %d","messagePattern":"unsupported frame flags: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proto/wire/wire.go","lineNumber":73,"sourceCode":"\nfunc NewConn(rw io.ReadWriter) *Conn {\n\treturn &Conn{\n\t\trw:                  rw,\n\t\tmaxFramePayloadSize: DefaultMaxFramePayloadSize,\n\t}\n}\n\nfunc (c *Conn) ReadFrame() (*Frame, error) {\n\theader := make([]byte, 8)\n\tif _, err := io.ReadFull(c.rw, header); err != nil {\n\t\treturn nil, err\n\t}\n\n\tframeType := binary.BigEndian.Uint16(header[0:2])\n\tflags := binary.BigEndian.Uint16(header[2:4])\n\tlength := binary.BigEndian.Uint32(header[4:8])\n\tif flags != 0 {\n\t\treturn nil, fmt.Errorf(\"unsupported frame flags: %d\", flags)\n\t}\n\tif length > c.maxFramePayloadSize {\n\t\treturn nil, fmt.Errorf(\"frame payload length %d exceeds limit %d\", length, c.maxFramePayloadSize)\n\t}\n\n\tpayload := make([]byte, length)\n\tif _, err := io.ReadFull(c.rw, payload); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Frame{\n\t\tType:    frameType,\n\t\tFlags:   flags,\n\t\tPayload: payload,\n\t}, nil\n}\n\nfunc (c *Conn) WriteFrame(f *Frame) error {\n\tif f.Flags != 0 {","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/proto/wire/wire.go#L55-L91","documentation":"Returned by Conn.ReadFrame when the incoming 8-byte frame header has a non-zero flags field. The framing protocol (type uint16, flags uint16, length uint32) reserves flags for future use but this build requires them to be zero; any non-zero value means the stream is corrupt or the peer speaks a newer protocol.","triggerScenarios":"The peer (or a middlebox) writes a frame with flags != 0; or the stream has desynchronized so that header bytes 2-4 are actually payload data. ReadFrame reads the header with io.ReadFull and immediately rejects non-zero flags.","commonSituations":"Stream desynchronization after an earlier partial read or a wrong payload-length assumption; connecting a newer frp peer that started using flag bits; writing raw bytes to the socket out-of-band from another goroutine.","solutions":["Check for concurrent writers on the same connection — interleaved writes corrupt the frame stream.","Verify both peers use the same protocol version; flag bits imply a protocol this build does not understand.","If it happens after a previous error, close the connection: the stream state is unrecoverable."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if _, err := conn.ReadFrame(); err != nil {\n    if strings.Contains(err.Error(), \"unsupported frame flags\") {\n        // stream desynced or newer peer protocol: close conn permanently, no recovery\n        conn.Close()\n    }\n    return err\n}","preventionTips":["Serialize all writes to a Conn from a single goroutine or a mutex.","Treat any framing error as fatal for the connection — never continue reading after one."],"tags":["protocol","framing","io","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}