{"record":{"id":"844210caa6a43163","repo":"golang/go","slug":"tls-server-selected-an-invalid-version-after-a-he","errorCode":null,"errorMessage":"tls: server selected an invalid version after a HelloRetryRequest","messagePattern":"tls: server selected an invalid version after a HelloRetryRequest","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client_tls13.go","lineNumber":175,"sourceCode":"\n\tc.isHandshakeComplete.Store(true)\n\n\treturn nil\n}\n\n// checkServerHelloOrHRR does validity checks that apply to both ServerHello and\n// HelloRetryRequest messages. It sets hs.suite.\nfunc (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {\n\tc := hs.c\n\n\tif hs.serverHello.supportedVersion == 0 {\n\t\tc.sendAlert(alertMissingExtension)\n\t\treturn errors.New(\"tls: server selected TLS 1.3 using the legacy version field\")\n\t}\n\n\tif hs.serverHello.supportedVersion != VersionTLS13 {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: server selected an invalid version after a HelloRetryRequest\")\n\t}\n\n\tif hs.serverHello.vers != VersionTLS12 {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: server sent an incorrect legacy version\")\n\t}\n\n\tif hs.serverHello.ocspStapling ||\n\t\ths.serverHello.ticketSupported ||\n\t\ths.serverHello.extendedMasterSecret ||\n\t\ths.serverHello.secureRenegotiationSupported ||\n\t\tlen(hs.serverHello.secureRenegotiation) != 0 ||\n\t\tlen(hs.serverHello.alpnProtocol) != 0 ||\n\t\tlen(hs.serverHello.scts) != 0 {\n\t\tc.sendAlert(alertUnsupportedExtension)\n\t\treturn errors.New(\"tls: server sent a ServerHello extension forbidden in TLS 1.3\")\n\t}\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client_tls13.go#L157-L193","documentation":"Thrown in checkServerHelloOrHRR() when the ServerHello's supported_versions extension contains a value other than TLS 1.3 (0x0304). Since the client entered the TLS 1.3 handshake code path, any version other than 1.3 in supported_versions is invalid.","triggerScenarios":"Triggered when hs.serverHello.supportedVersion is non-zero but != VersionTLS13. The client sends alertIllegalParameter. This can occur in either an initial ServerHello or a HelloRetryRequest.","commonSituations":"Server bug negotiating a wrong version in the supported_versions extension. TLS downgrade attack where an attacker modifies the extension value. Non-compliant server mixing TLS version fields. HelloRetryRequest with a version the client didn't expect.","solutions":["This indicates a server-side protocol violation — verify the server's TLS implementation is correct.","If the server only supports TLS 1.2, configure the client to not offer TLS 1.3 rather than forcing a mismatch.","Check for middlebox or proxy interference modifying the supported_versions extension.","Report the bug to the server software vendor with a packet capture."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"conn, err := tls.Dial(\"tcp\", addr, config)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid version after a HelloRetryRequest\") {\n        // Server protocol violation — attempt TLS 1.2 fallback\n        config.MaxVersion = tls.VersionTLS12\n        conn, err = tls.Dial(\"tcp\", addr, config)\n    }\n}","preventionTips":["Use Wireshark to capture and verify the supported_versions extension in server responses.","Report server-side TLS 1.3 implementation bugs to the vendor.","Maintain a fallback configuration for non-compliant servers."],"tags":["tls","go","tls13","version-negotiation","protocol-violation","rfc8446"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}