{"record":{"id":"3ae1f5edceb4961c","repo":"golang/go","slug":"tls-malformed-key-share-extension","errorCode":null,"errorMessage":"tls: malformed key_share extension","messagePattern":"tls: malformed key_share extension","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client_tls13.go","lineNumber":427,"sourceCode":"\treturn nil\n}\n\nfunc (hs *clientHandshakeStateTLS13) processServerHello() error {\n\tc := hs.c\n\n\tif bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {\n\t\tc.sendAlert(alertUnexpectedMessage)\n\t\treturn errors.New(\"tls: server sent two HelloRetryRequest messages\")\n\t}\n\n\tif len(hs.serverHello.cookie) != 0 {\n\t\tc.sendAlert(alertUnsupportedExtension)\n\t\treturn errors.New(\"tls: server sent a cookie in a normal ServerHello\")\n\t}\n\n\tif hs.serverHello.selectedGroup != 0 {\n\t\tc.sendAlert(alertDecodeError)\n\t\treturn errors.New(\"tls: malformed key_share extension\")\n\t}\n\n\tif hs.serverHello.serverShare.group == 0 {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: server did not send a key share\")\n\t}\n\tif !slices.ContainsFunc(hs.hello.keyShares, func(ks keyShare) bool {\n\t\treturn ks.group == hs.serverHello.serverShare.group\n\t}) {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: server selected unsupported group\")\n\t}\n\n\tif !hs.serverHello.selectedIdentityPresent {\n\t\treturn nil\n\t}\n\n\tif int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client_tls13.go#L409-L445","documentation":"In a normal ServerHello, the key_share extension carries the server's share but must NOT also include the selectedGroup field (that field is HRR-only per RFC 8446 §4.2.8). Go treats a non-zero selectedGroup here as a malformed message and sends `decode_error`. The server is encoding the extension incorrectly.","triggerScenarios":"ServerHello.selectedGroup != 0 in processServerHello. Means the server put the HRR-shaped key_share (with selected_group) into a normal ServerHello.","commonSituations":"Hand-rolled or buggy TLS 1.3 server, fuzz traffic, or a middlebox that rewrites the key_share extension. Stock compliant servers never produce this.","solutions":["Report the malformed extension to the server operator.","Verify with a packet capture which side injects selectedGroup into the ServerHello.","Test against a reference Go tls.Server peer to localise the fault.","Patch the server's key_share encoder to use the ServerHello shape (server_share only)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"malformed key_share extension\") {\n        log.Printf(\"peer sent selected_group in a non-HRR ServerHello: %v\", err)\n    }\n    return err\n}","preventionTips":["Treat malformed-extension errors as fatal for the peer; investigate before reconnecting.","Packet-capture handshakes when these errors appear to confirm the source.","Reject middleboxes that rewrite key_share."],"tags":["tls","tls13","handshake","key-share","protocol-violation","network","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}