{"record":{"id":"9b6b50ccdc85b01a","repo":"golang/go","slug":"tls-no-supported-elliptic-curves-offered","errorCode":null,"errorMessage":"tls: no supported elliptic curves offered","messagePattern":"tls: no supported elliptic curves offered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/key_agreement.go","lineNumber":167,"sourceCode":"\tpreMasterSecret []byte\n\n\t// curveID, signatureAlgorithm, and key are set by processServerKeyExchange\n\t// and generateServerKeyExchange.\n\tcurveID            CurveID\n\tsignatureAlgorithm SignatureScheme\n\tkey                *ecdh.PrivateKey\n}\n\nfunc (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {\n\tfor _, c := range clientHello.supportedCurves {\n\t\tif config.supportsCurve(ka.version, c) {\n\t\t\tka.curveID = c\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif ka.curveID == 0 {\n\t\treturn nil, errors.New(\"tls: no supported elliptic curves offered\")\n\t}\n\tif _, ok := curveForCurveID(ka.curveID); !ok {\n\t\treturn nil, errors.New(\"tls: internal error: supportsCurve accepted unimplemented curve\")\n\t}\n\n\tkey, err := generateECDHEKey(config.rand(), ka.curveID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tka.key = key\n\n\t// See RFC 4492, Section 5.4.\n\tecdhePublic := key.PublicKey().Bytes()\n\tserverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))\n\tserverECDHEParams[0] = 3 // named curve\n\tserverECDHEParams[1] = byte(ka.curveID >> 8)\n\tserverECDHEParams[2] = byte(ka.curveID)\n\tserverECDHEParams[3] = byte(len(ecdhePublic))","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/key_agreement.go#L149-L185","documentation":"During TLS 1.0–1.2 ECDHE key exchange, the server iterates the client's supportedCurves list looking for one that the server also supports (via config.supportsCurve). If no overlap is found (ka.curveID remains 0), the server cannot proceed with ECDHE key exchange. The client must offer at least one curve the server supports.","triggerScenarios":"Server calls ecdheKeyAgreement.generateServerKeyExchange. The clientHello.supportedCurves list is empty, or contains only curves the server doesn't support (e.g. client offers only custom/obsolete curves the server's config rejects).","commonSituations":"Client offers only non-standard or deprecated curves; server's CurvePreferences list is too restrictive; client configured with an empty or exotic supported curves list; version mismatch where a client only supports curves the server dropped; FIPS-mode server that restricts curve selection.","solutions":["Ensure the client offers at least one standard curve the server supports (X25519, P-256, P-384 are universally recommended).","On the server, verify tls.Config.CurvePreferences includes common curves (or leave it nil for defaults).","Update the client TLS library to one that advertises standard curves.","If running in FIPS mode, ensure the client offers NIST curves (P-256, P-384) since X25519 may not be available.","Prefer TLS 1.3 which has better curve negotiation and defaults."],"exampleFix":"// before: client offers no supported curves (or server restricts too much)\ncfg := &tls.Config{\n    CurvePreferences: []tls.CurveID{}, // empty - too restrictive\n}\n// after: include standard curves\ncfg := &tls.Config{\n    CurvePreferences: []tls.CurveID{\n        tls.X25519, tls.CurveP256, tls.CurveP384,\n    },\n}","handlingStrategy":"validation","validationCode":"// Server-side: verify curve configuration before accepting connections\nfunc validateCurveConfig(cfg *tls.Config) error {\n    if len(cfg.CurvePreferences) == 0 {\n        return nil // defaults are fine\n    }\n    standardCurves := map[tls.CurveID]bool{\n        tls.X25519: true, tls.CurveP256: true, tls.CurveP384: true, tls.CurveP521: true,\n    }\n    for _, c := range cfg.CurvePreferences {\n        if !standardCurves[c] {\n            return fmt.Errorf(\"non-standard curve %v in preferences\", c)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Server-side: log and close\nif err := conn.Handshake(); err != nil {\n    if strings.Contains(err.Error(), \"no supported elliptic curves\") {\n        log.Printf(\"client offered no supported curves: %v\", err)\n    }\n    conn.Close()\n}","preventionTips":["Include standard curves (X25519, P-256, P-384) in CurvePreferences.","Don't empty or over-restrict CurvePreferences.","Monitor this error to detect clients with outdated curve support.","For FIPS environments, ensure clients offer NIST curves."],"tags":["tls","tls12","ecdhe","key-exchange","curves","cipher-suite","server-side"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}