golang/go · error
unsupported curve
Error message
unsupported curve
What it means
unsupportedCurveKEM is a sentinel returned by DHKEM() when the supplied ecdh.Curve is not P-256/P-384/P-521/X25519. Every method on this sentinel returns "unsupported curve". Because ecdh.Curve is a closed interface (unexported methods), this default branch is only reachable if a new curve type is added to the standard library or by an internal fork.
Source
Thrown at src/crypto/hpke/kem.go:171
case ecdh.P521():
return dhKEMP521
case ecdh.X25519():
return dhKEMX25519
default:
// The set of ecdh.Curve implementations is closed, because the
// interface has unexported methods. Therefore, this default case is
// only hit if a new curve is added that DHKEM doesn't support.
return unsupportedCurveKEM{}
}
}
type unsupportedCurveKEM struct{}
func (unsupportedCurveKEM) ID() uint16 {
return 0
}
func (unsupportedCurveKEM) GenerateKey() (PrivateKey, error) {
return nil, errors.New("unsupported curve")
}
func (unsupportedCurveKEM) NewPublicKey([]byte) (PublicKey, error) {
return nil, errors.New("unsupported curve")
}
func (unsupportedCurveKEM) NewPrivateKey([]byte) (PrivateKey, error) {
return nil, errors.New("unsupported curve")
}
func (unsupportedCurveKEM) DeriveKeyPair([]byte) (PrivateKey, error) {
return nil, errors.New("unsupported curve")
}
func (unsupportedCurveKEM) encSize() int {
return 0
}
type dhKEMPublicKey struct {
kem *dhKEM
pub *ecdh.PublicKey
}View on GitHub (pinned to b6b368adc5)
Solutions
- Pass one of ecdh.P256(), ecdh.P384(), ecdh.P521(), or ecdh.X25519() to DHKEM.
- Upgrade the vendored crypto/hpke to match the toolchain's crypto/ecdh.
- Avoid constructing ecdh.Curve values from external input.
Example fix
// before kem := hpke.DHKEM(someNewCurve) k, err := kem.GenerateKey() // "unsupported curve" // after kem := hpke.DHKEM(ecdh.X25519()) k, err := kem.GenerateKey()
Defensive patterns
Strategy: validation
Validate before calling
func supportedDHCurve(c ecdh.Curve) bool {
switch c {
case ecdh.P256(), ecdh.P384(), ecdh.P521(), ecdh.X25519():
return true
}
return false
}
func generateKey(c ecdh.Curve) (hpke.PrivateKey, error) {
if !supportedDHCurve(c) {
return nil, fmt.Errorf("curve %v not supported by DHKEM", c)
}
return hpke.DHKEM(c).GenerateKey()
} Try / catch
k, err := kem.GenerateKey()
if err != nil && err.Error() == "unsupported curve" {
return fmt.Errorf("DHKEM returned sentinel; pass a supported ecdh.Curve")
} Prevention
- Never construct ecdh.Curve values from external/untrusted input.
- Pin the supported curve set in one helper used by every caller.
- Upgrade vendored crypto/hpke when adopting a newer Go toolchain.
When it happens
Trigger: DHKEM(unknownCurve).GenerateKey() where unknownCurve is any ecdh.Curve outside the four supported. In practice reachable only by a fork that introduces a new ecdh.Curve constant, or by a future stdlib addition this build predates.
Common situations: Vendoring an older copy of crypto/hpke into a toolchain whose crypto/ecdh gained a new curve; or a downstream fork adding experimental curves.
Related errors
- unsupported KEM
- ecdh: private key does not support Bytes
- export-only instantiation
- invalid length
- ciphertext too short
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/c589b8ffe4c6f6dc.
Report an issue: GitHub.