{"record":{"id":"615e0739e3b5b046","repo":"golang/go","slug":"tls-server-selected-unsupported-curve","errorCode":null,"errorMessage":"tls: server selected unsupported curve","messagePattern":"tls: server selected unsupported curve","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/key_agreement.go","lineNumber":276,"sourceCode":"\n\tpeerKey, err := ka.key.Curve().NewPublicKey(ckx.ciphertext[1:])\n\tif err != nil {\n\t\treturn nil, errClientKeyExchange\n\t}\n\tpreMasterSecret, err := ka.key.ECDH(peerKey)\n\tif err != nil {\n\t\treturn nil, errClientKeyExchange\n\t}\n\n\treturn preMasterSecret, nil\n}\n\nfunc (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {\n\tif len(skx.key) < 4 {\n\t\treturn errServerKeyExchange\n\t}\n\tif skx.key[0] != 3 { // named curve\n\t\treturn errors.New(\"tls: server selected unsupported curve\")\n\t}\n\tka.curveID = CurveID(skx.key[1])<<8 | CurveID(skx.key[2])\n\n\tpublicLen := int(skx.key[3])\n\tif publicLen+4 > len(skx.key) {\n\t\treturn errServerKeyExchange\n\t}\n\tserverECDHEParams := skx.key[:4+publicLen]\n\tpublicKey := serverECDHEParams[4:]\n\n\tsig := skx.key[4+publicLen:]\n\tif len(sig) < 2 {\n\t\treturn errServerKeyExchange\n\t}\n\tif ka.version >= VersionTLS12 {\n\t\tka.signatureAlgorithm = SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])\n\t\tsig = sig[2:]\n\t\tif len(sig) < 2 {","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/key_agreement.go#L258-L294","documentation":"During TLS 1.0–1.2 ECDHE key exchange on the client side, the server's ServerKeyExchange message specified a curve type other than 'named_curve' (3). The first byte of the ECDHE params (skx.key[0]) must be 3 per RFC 4492/8422; any other value (e.g. 1=explicit_prime or 2=explicit_char2) is rejected because Go's crypto/tls only supports named curves.","triggerScenarios":"Client calls ecdheKeyAgreement.processServerKeyExchange and the first byte of skx.key is not 3. The server sent an explicit curve parameter set (deprecated in RFC 8422) instead of a named curve ID.","commonSituations":"Server uses a very old or non-conformant TLS library that sends explicit curve parameters; a custom server implementation that doesn't use named curves; a MITM altering the ServerKeyExchange; testing against an old server that predates RFC 8422 deprecation of explicit curves.","solutions":["Update the server to a modern TLS library that uses named curves (curve type 3).","Verify no intermediary is modifying the ServerKeyExchange message.","If you control the server, ensure it only sends named_curve ECDHE parameters.","Capture the ServerKeyExchange with Wireshark and check the ECParameters curve_type field.","Use TLS 1.3 which eliminates this legacy parameter format."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Client-side: no pre-check is possible since the server controls ServerKeyExchange.\n// You can restrict cipher suites to avoid ECDHE with non-conformant servers:\n// Prefer TLS 1.3 which doesn't have this format issue.\nfunc preferTLS13(cfg *tls.Config) {\n    cfg.MinVersion = tls.VersionTLS13\n}","typeGuard":null,"tryCatchPattern":"// Client-side: handle during handshake\nif err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"server selected unsupported curve\") {\n        log.Printf(\"server sent non-named-curve ECDHE params: %v\", err)\n        // Server is non-conformant or very old — upgrade or avoid\n    }\n}","preventionTips":["Prefer TLS 1.3 which eliminates legacy ECDHE parameter formats.","Avoid TLS 1.0/1.1 connections to very old servers.","Test against modern servers that use named curves.","Report non-conformant servers to their maintainers."],"tags":["tls","tls12","ecdhe","key-exchange","server-key-exchange","curves","client-side"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}