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.

Solutions

  1. Pass one of ecdh.P256(), ecdh.P384(), ecdh.P521(), or ecdh.X25519() to DHKEM.
  2. Upgrade the vendored crypto/hpke to match the toolchain's crypto/ecdh.
  3. 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

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


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/c589b8ffe4c6f6dc. Report an issue: GitHub.

Appendix: 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)