{"record":{"id":"fd04ccfc315261e6","repo":"fatedier/frp","slug":"invalid-crypto-server-random-length-d-want-d","errorCode":null,"errorMessage":"invalid crypto server random length %d, want %d","messagePattern":"invalid crypto server random length (.+?), want (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proto/wire/crypto.go","lineNumber":113,"sourceCode":"\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 {\n\treturn &CryptoContext{\n\t\tAlgorithm:      algorithm,\n\t\tTranscriptHash: HashCryptoTranscript(clientHelloPayload, serverHelloPayload),\n\t}\n}\n","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/proto/wire/crypto.go#L95-L131","documentation":"Thrown by ValidateServerHelloForClient when ServerHello.Selected.Crypto.ServerRandom is not exactly CryptoRandomSize (32) bytes. The server random feeds key derivation, so a wrong length indicates a broken or truncated handshake message.","triggerScenarios":"Server sends Selected.Crypto.ServerRandom that is nil, empty, or any length other than 32 bytes (e.g. 16-byte random, base64 string put in the field raw instead of decoded, or hex-encoded 64 bytes).","commonSituations":"Test mocks that fill the field with random data of arbitrary size; a JSON encoding path where the []byte is marshaled as base64 and then re-marshaled as a string on the other side, doubling length; older servers that used a different random size.","solutions":["Generate ServerRandom with the same helper the library uses: 32 bytes from crypto/rand (see newCryptoRandom / CryptoRandomSize).","Ensure the []byte field survives JSON round-trips as base64 — do not convert it to a hex string manually.","Check for payload truncation if the error appears only in production (MTU/proxy issues mangling the hello frame)."],"exampleFix":"// before\nselected.Crypto.ServerRandom = make([]byte, 16)\n\n// after\nrandom, err := newCryptoRandom() // 32 bytes, crypto/rand\nif err != nil { return err }\nselected.Crypto.ServerRandom = random","handlingStrategy":"validation","validationCode":"if got := len(serverHello.Selected.Crypto.ServerRandom); got != wire.CryptoRandomSize {\n    return fmt.Errorf(\"server random is %d bytes, want %d — truncated or mis-encoded hello\", got, wire.CryptoRandomSize)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate randoms with crypto/rand at exactly wire.CryptoRandomSize bytes.","Never hand-encode []byte random fields as hex strings; JSON base64 of the raw bytes is the only correct form."],"tags":["crypto","handshake","validation","go"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}