golang/go · error
connection doesn't support Ed25519
Error message
connection doesn't support Ed25519
What it means
A server certificate uses an Ed25519 public key, but the client connection cannot use Ed25519 for signing. TLS permits Ed25519 only from TLS 1.2 onward and requires the client to advertise at least one signature scheme in its ClientHello (signature_algorithms extension). If either precondition fails, the certificate is rejected as incompatible with the connection.
Source
Thrown at src/crypto/tls/common.go:1504
case elliptic.P521():
curve = CurveP521
default:
return supportsRSAFallback(unsupportedCertificateError(c))
}
var curveOk bool
for _, c := range chi.SupportedCurves {
if c == curve && config.supportsCurve(vers, c) {
curveOk = true
break
}
}
if !curveOk {
return errors.New("client doesn't support certificate curve")
}
ecdsaCipherSuite = true
case ed25519.PublicKey:
if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 {
return errors.New("connection doesn't support Ed25519")
}
ecdsaCipherSuite = true
case *mldsa.PublicKey:
// ML-DSA requires TLS 1.3, which we already excluded above.
return errors.New("connection doesn't support ML-DSA")
case *rsa.PublicKey:
default:
return supportsRSAFallback(unsupportedCertificateError(c))
}
} else {
return supportsRSAFallback(unsupportedCertificateError(c))
}
// Make sure that there is a mutually supported cipher suite that works with
// this certificate. Cipher suite selection will then apply the logic in
// reverse to pick it. See also serverHandshakeState.cipherSuiteOk.
cipherSuite := selectCipherSuite(chi.CipherSuites, config.supportedCipherSuites(), func(c *cipherSuite) bool {
if c.flags&suiteECDHE == 0 {View on GitHub (pinned to b6b368adc5)
Solutions
- Upgrade the negotiated TLS version to at least 1.2 (set MinVersion to tls.VersionTLS12 on the client config)
- Ensure the client advertises signature schemes — use a standard tls.Config rather than a hand-built ClientHello; if customizing, populate SignatureSchemes with ed25519 values
- Replace the server certificate's Ed25519 key with an ECDSA/RSA key compatible with the client's capabilities
Example fix
// before: client MinVersion left at default TLS 1.0
cfg := &tls.Config{ /* MinVersion unset */ }
// after
cfg := &tls.Config{MinVersion: tls.VersionTLS12} Defensive patterns
Strategy: validation
Validate before calling
// Before offering the cert, check compatibility
func ed25519Compatible(vers uint16, sigSchemes []tls.SignatureScheme) bool {
if vers < tls.VersionTLS12 || len(sigSchemes) == 0 {
return false
}
for _, s := range sigSchemes {
if s == tls.PSSWithSHA256 /* etc */ || s == 0x0807 /* ed25519 */ {
return true
}
}
return false
} Type guard
func isEd25519Cert(c *tls.Certificate) bool {
pub, ok := c.PrivateKey.(crypto.Signer)
return ok && reflect.TypeOf(pub.Public()) == reflect.TypeOf(ed25519.PublicKey{})
} Try / catch
if _, err := cfg.BuildTLSConfig(); err != nil {
var unsupported interface{ Unwrap() error }
_ = unsupported
} Prevention
- Set MinVersion = tls.VersionTLS12 globally on client configs
- Prefer ECDSA/RSA certs for broad client compatibility; reserve Ed25519 for known-modern peers
- Validate cert key type against negotiated protocol version in test fixtures
When it happens
Trigger: serverCapabilitiesOfCertificate / supportsCertificate evaluates a *Certificate whose leaf public key is ed25519.PublicKey, while vers < VersionTLS12 OR len(chi.SignatureSchemes) == 0.
Common situations: Configuring a TLS 1.0/1.1-only client against an Ed25519 certificate; a legacy/bespoke client that omits the signature_algorithms extension; a server with an Ed25519 leaf cert being matched to a very old or minimal ClientHello.
Related errors
- tls: received empty certificates message
- tls: failed to sign handshake: %s
- Ed25519 verification failure
- tls: missing signature_algorithms from TLS 1.2 peer
- tls: peer doesn't support any of the certificate's signature
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/8f1ad4ad23d575a5.
Report an issue: GitHub.