golang/go · error
unsupported KEM
Error message
unsupported KEM
What it means
NewKEM maps a numeric KEM ID (IANA HPKE registry) to an implementation. Only specific IDs are recognised: 0x0010-0x0012 (DHKEM P-256/P-384/P-521), 0x0020 (DHKEM X25519), 0x0041/0x0042 (ML-KEM-768/1024), 0x647a (MLKEM768-X25519), 0x0050 (MLKEM768-P256), 0x0051 (MLKEM1024-P384). Any other value falls through to the error.
Source
Thrown at src/crypto/hpke/kem.go:67
return DHKEM(ecdh.P256()), nil
case 0x0011: // DHKEM(P-384, HKDF-SHA384)
return DHKEM(ecdh.P384()), nil
case 0x0012: // DHKEM(P-521, HKDF-SHA512)
return DHKEM(ecdh.P521()), nil
case 0x0020: // DHKEM(X25519, HKDF-SHA256)
return DHKEM(ecdh.X25519()), nil
case 0x0041: // ML-KEM-768
return MLKEM768(), nil
case 0x0042: // ML-KEM-1024
return MLKEM1024(), nil
case 0x647a: // MLKEM768-X25519
return MLKEM768X25519(), nil
case 0x0050: // MLKEM768-P256
return MLKEM768P256(), nil
case 0x0051: // MLKEM1024-P384
return MLKEM1024P384(), nil
default:
return nil, errors.New("unsupported KEM")
}
}
// A PublicKey is an instantiation of a KEM (one of the three components of an
// HPKE ciphersuite) with an encapsulation key (i.e. the public key).
//
// A PublicKey is usually obtained from a method of the corresponding [KEM] or
// [PrivateKey], such as [KEM.NewPublicKey] or [PrivateKey.PublicKey].
type PublicKey interface {
// KEM returns the instantiated KEM.
KEM() KEM
// Bytes returns the public key as the output of SerializePublicKey.
Bytes() []byte
encap() (sharedSecret, enc []byte, err error)
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Use a symbolic constructor (DHKEM, MLKEM768, MLKEM768X25519, etc.) instead of a raw numeric ID.
- Cross-check the ID against RFC 9180 §36 and the IANA HPKE registry before passing it in.
- Verify endianness: KEM IDs in HPKE are big-endian uint16.
Example fix
// before kem, err := hpke.NewKEM(0x1000) // transposed -> "unsupported KEM" // after kem, err := hpke.NewKEM(0x0010) // DHKEM(P-256) // or, preferred: kem := hpke.DHKEM(ecdh.P256())
Defensive patterns
Strategy: validation
Validate before calling
// Allowlist of supported KEM IDs for this build.
var supportedKEMs = map[uint16]string{
0x0010: "DHKEM(P-256)", 0x0011: "DHKEM(P-384)", 0x0012: "DHKEM(P-521)",
0x0020: "DHKEM(X25519)", 0x0041: "ML-KEM-768", 0x0042: "ML-KEM-1024",
0x647A: "MLKEM768-X25519", 0x0050: "MLKEM768-P256", 0x0051: "MLKEM1024-P384",
}
func kemFor(id uint16) (hpke.KEM, error) {
if _, ok := supportedKEMs[id]; !ok {
return nil, fmt.Errorf("KEM 0x%04x not supported by this build", id)
}
return hpke.NewKEM(id)
} Try / catch
kem, err := hpke.NewKEM(id)
if err != nil {
if err.Error() == "unsupported KEM" {
return fmt.Errorf("unknown KEM id 0x%04x; check IANA HPKE registry", id)
}
return err
} Prevention
- Prefer symbolic constructors (DHKEM, MLKEM768X25519) over numeric IDs.
- Cross-check every hardcoded ID against the IANA HPKE registry.
- Store KEM IDs in typed constants to avoid digit transposition.
When it happens
Trigger: Calling hpke.NewKEM(id) with an unregistered, mistyped, or unsupported KEM ID. Also hit by byte-order mistakes (e.g. passing 0x1000 instead of 0x0010).
Common situations: Hardcoding a KEM ID from memory and transposing digits; reading an ID off the wire that the local build doesn't support; using a future/draft KEM ID not yet implemented.
Related errors
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/469d29cb5fef8434.
Report an issue: GitHub.