{"record":{"id":"5b5b2127b6240d44","repo":"fatedier/frp","slug":"unknown-selected-crypto-algorithm-s","errorCode":null,"errorMessage":"unknown selected crypto algorithm: %s","messagePattern":"unknown selected crypto algorithm: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proto/wire/crypto.go","lineNumber":107,"sourceCode":"\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\nfunc selectUDPPacketCodec(codecs []string) string {\n\tif Supports(codecs, UDPPacketCodecBinary) {\n\t\treturn UDPPacketCodecBinary\n\t}\n\treturn \"\"\n}\n\nfunc NewCryptoContext(algorithm string, clientHelloPayload, serverHelloPayload []byte) *CryptoContext {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/proto/wire/crypto.go#L89-L125","documentation":"Thrown by ValidateServerHelloForClient when the crypto algorithm in ServerHello.Selected.Crypto.Algorithm is not in supportedAEADAlgorithms (\"aes-256-gcm\" or \"xchacha20-poly1305\"). This catches servers that select an algorithm this build cannot instantiate, before any AEAD cipher is constructed.","triggerScenarios":"Server sends an algorithm string outside the supported set — empty string, \"aes-128-gcm\", typo, or an algorithm introduced in a newer frp version. Detected in NewClientCryptoContext after decoding the ServerHello transcript.","commonSituations":"Version mismatch between client and server; corrupted handshake bytes that still parse as JSON; malicious server attempting to downgrade to a weak/unknown cipher.","solutions":["Run the same frp version on client and server so the supported algorithm sets are identical.","On the server, select the algorithm only via SelectAEADAlgorithm(clientHello...Algorithms), never from config strings or user input.","Verify the ServerHello payload is not being truncated or modified in transit (TLS/proxy setups that mangle bodies)."],"exampleFix":"// before (server, hand-rolled)\nselected.Crypto.Algorithm = \"aes-128-gcm\"\n\n// after\nalgorithm, ok := wire.SelectAEADAlgorithm(clientHello.Capabilities.Crypto.Algorithms)\nif !ok { return errors.New(\"no shared algorithm\") }\nselected.Crypto.Algorithm = algorithm","handlingStrategy":"validation","validationCode":"if !wire.IsSupportedAEADAlgorithm(serverHello.Selected.Crypto.Algorithm) {\n    return fmt.Errorf(\"server selected unknown algorithm %q — likely version mismatch\",\n        serverHello.Selected.Crypto.Algorithm)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Servers: select algorithms only via SelectAEADAlgorithm over the client's list.","Deploy matching frp versions on both peers."],"tags":["crypto","handshake","protocol-negotiation","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}