golang/go · critical
tls: internal error: supportsCurve accepted unimplemented cu
Error message
tls: internal error: supportsCurve accepted unimplemented curve
What it means
An internal invariant violation: config.supportsCurve returned true for a curve ID, but curveForCurveID could not map that same curve ID to an actual elliptic curve implementation. This means supportsCurve is accepting a curve that generateECDHEKey cannot handle. This error indicates a bug in the crypto/tls package itself — supportsCurve and curveForCurveID are out of sync.
Source
Thrown at src/crypto/tls/key_agreement.go:170
// and generateServerKeyExchange.
curveID CurveID
signatureAlgorithm SignatureScheme
key *ecdh.PrivateKey
}
func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
for _, c := range clientHello.supportedCurves {
if config.supportsCurve(ka.version, c) {
ka.curveID = c
break
}
}
if ka.curveID == 0 {
return nil, errors.New("tls: no supported elliptic curves offered")
}
if _, ok := curveForCurveID(ka.curveID); !ok {
return nil, errors.New("tls: internal error: supportsCurve accepted unimplemented curve")
}
key, err := generateECDHEKey(config.rand(), ka.curveID)
if err != nil {
return nil, err
}
ka.key = key
// See RFC 4492, Section 5.4.
ecdhePublic := key.PublicKey().Bytes()
serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))
serverECDHEParams[0] = 3 // named curve
serverECDHEParams[1] = byte(ka.curveID >> 8)
serverECDHEParams[2] = byte(ka.curveID)
serverECDHEParams[3] = byte(len(ecdhePublic))
copy(serverECDHEParams[4:], ecdhePublic)
priv, ok := cert.PrivateKey.(crypto.Signer)View on GitHub (pinned to b6b368adc5)
Solutions
- If using a stock Go installation, report this as a Go runtime bug.
- If using a forked crypto/tls, verify that every curve accepted by supportsCurve has a corresponding entry in curveForCurveID.
- Rebuild from a clean source tree to rule out corruption.
- Check that the Go version is not from a broken or experimental build.
Defensive patterns
Strategy: try-catch
Validate before calling
// Internal invariant — no pre-check is possible.
// Verify you're using an unmodified Go standard library:
func checkGoTLSVersion() error {
// This error should never occur with stock Go
return nil
} Try / catch
// If this fires, it's a bug in the crypto/tls package or a fork
if err := conn.Handshake(); err != nil {
if strings.Contains(err.Error(), "supportsCurve accepted unimplemented curve") {
log.Printf("BUG: internal curve registry inconsistency: %v", err)
// Report to Go team if using stock Go
}
} Prevention
- Use unmodified Go standard library.
- If forking crypto/tls, keep supportsCurve and curveForCurveID in sync.
- Report immediately if seen with stock Go.
- Verify build integrity if this error appears.
When it happens
Trigger: Theoretically unreachable in a correctly functioning standard library. Would fire if someone added a CurveID to the supported list in supportsCurve but forgot to register it in curveForCurveID, or vice versa.
Common situations: A forked or modified crypto/tls package where supportsCurve and curveForCurveID were updated inconsistently; a build from a corrupted or incomplete source tree; extremely unlikely with stock Go.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: no supported elliptic curves offered
- tls: certificate cannot be used with the selected cipher sui
- tls: failed to sign ECDHE parameters: %s
- tls: server selected unsupported curve
- tls: internal error: unknown cipher suite
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/f37dfa5a2b2f5efa.
Report an issue: GitHub.