{"record":{"id":"d9031193d187ee43","repo":"fatedier/frp","slug":"unsupported-selected-udp-packet-codec-s","errorCode":null,"errorMessage":"unsupported selected UDP packet codec: %s","messagePattern":"unsupported selected UDP packet codec: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proto/wire/crypto.go","lineNumber":99,"sourceCode":"\nfunc ValidateCryptoCapabilities(c CryptoCapabilities) error {\n\tif len(c.ClientRandom) != CryptoRandomSize {\n\t\treturn fmt.Errorf(\"invalid crypto client random length %d, want %d\", len(c.ClientRandom), CryptoRandomSize)\n\t}\n\tif _, ok := SelectAEADAlgorithm(c.Algorithms); !ok {\n\t\treturn fmt.Errorf(\"no supported crypto algorithm\")\n\t}\n\treturn nil\n}\n\nfunc ValidateServerHelloForClient(clientHello ClientHello, serverHello ServerHello) error {\n\tif serverHello.Selected.Message.Codec != MessageCodecJSON {\n\t\treturn fmt.Errorf(\"unsupported selected message codec: %s\", serverHello.Selected.Message.Codec)\n\t}\n\tudpPacketCodec := serverHello.Selected.Message.UDPPacketCodec\n\tif udpPacketCodec != \"\" {\n\t\tif udpPacketCodec != UDPPacketCodecBinary {\n\t\t\treturn fmt.Errorf(\"unsupported selected UDP packet codec: %s\", udpPacketCodec)\n\t\t}\n\t\tif !Supports(clientHello.Capabilities.Message.UDPPacketCodecs, udpPacketCodec) {\n\t\t\treturn fmt.Errorf(\"selected UDP packet codec was not advertised by client: %s\", udpPacketCodec)\n\t\t}\n\t}\n\tcryptoSelection := serverHello.Selected.Crypto\n\tif !IsSupportedAEADAlgorithm(cryptoSelection.Algorithm) {\n\t\treturn fmt.Errorf(\"unknown selected crypto algorithm: %s\", cryptoSelection.Algorithm)\n\t}\n\tif !Supports(clientHello.Capabilities.Crypto.Algorithms, cryptoSelection.Algorithm) {\n\t\treturn fmt.Errorf(\"selected crypto algorithm was not advertised by client: %s\", cryptoSelection.Algorithm)\n\t}\n\tif len(cryptoSelection.ServerRandom) != CryptoRandomSize {\n\t\treturn fmt.Errorf(\"invalid crypto server random length %d, want %d\", len(cryptoSelection.ServerRandom), CryptoRandomSize)\n\t}\n\treturn nil\n}\n","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/proto/wire/crypto.go#L81-L117","documentation":"Thrown by ValidateServerHelloForClient when the ServerHello selects a UDP packet codec other than \"\" (none) or UDPPacketCodecBinary. Binary is currently the only UDP packet codec implemented, so any other value in Selected.Message.UDPPacketCodec is rejected before the session proceeds.","triggerScenarios":"Server sends ServerHello with Selected.Message.UDPPacketCodec set to a non-empty value that is not \"binary\" (e.g. a future codec name or a typo), while validating the hello on the client via NewClientCryptoContext.","commonSituations":"Version skew where a newer server supports an additional UDP packet codec; mock servers in e2e tests that populate the field incorrectly; corrupted or tampered handshake payloads.","solutions":["Have the server use selectUDPPacketCodec() which only ever returns \"binary\" or \"\" — do not hand-pick codec names.","Upgrade/downgrade both peers to the same frp release so the codec vocabulary matches.","Fix test fixtures to leave UDPPacketCodec empty or set it to wire.UDPPacketCodecBinary."],"exampleFix":"// before\nserverHello.Selected.Message.UDPPacketCodec = \"raw\"\n\n// after\nserverHello.Selected.Message.UDPPacketCodec = wire.UDPPacketCodecBinary // or \"\" for none","handlingStrategy":"validation","validationCode":"codec := serverHello.Selected.Message.UDPPacketCodec\nif codec != \"\" && codec != wire.UDPPacketCodecBinary {\n    return fmt.Errorf(\"refusing handshake: UDP packet codec %q unsupported\", codec)\n}","typeGuard":null,"tryCatchPattern":"if err := wire.NewClientCryptoContext(clientRaw, serverRaw); err != nil {\n    if strings.Contains(err.Error(), \"UDP packet codec\") {\n        // protocol mismatch — fail fast, close conn, no retry\n    }\n    return err\n}","preventionTips":["Servers must select UDP packet codecs only through selectUDPPacketCodec semantics (binary or none).","Keep hello fixtures generated by shared helpers, not copied structs."],"tags":["handshake","udp","codec","protocol-negotiation","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}