golang/go · error
unsupported public key type
Error message
unsupported public key type
What it means
Raised by NewMLKEMPublicKey when the supplied crypto.Encapsulator is neither *mlkem.EncapsulationKey768 nor *mlkem.EncapsulationKey1024. These are the only two ML-KEM parameter sets exposed as standalone HPKE public keys.
Source
Thrown at src/crypto/hpke/pq.go:437
// NewMLKEMPublicKey returns a KEMPublicKey implementing
//
// - ML-KEM-768
// - ML-KEM-1024
//
// from draft-ietf-hpke-pq, depending on the type of pub
// (*[mlkem.EncapsulationKey768] or *[mlkem.EncapsulationKey1024]).
//
// This function is meant for applications that already have an instantiated
// crypto/mlkem public key. Otherwise, applications should use the
// [KEM.NewPublicKey] method of e.g. [MLKEM768].
func NewMLKEMPublicKey(pub crypto.Encapsulator) (PublicKey, error) {
switch pub.(type) {
case *mlkem.EncapsulationKey768:
return &mlkemPublicKey{mlkem768, pub}, nil
case *mlkem.EncapsulationKey1024:
return &mlkemPublicKey{mlkem1024, pub}, nil
default:
return nil, errors.New("unsupported public key type")
}
}
func (kem *mlkemKEM) NewPublicKey(data []byte) (PublicKey, error) {
pq, err := kem.newPublicKey(data)
if err != nil {
return nil, err
}
return NewMLKEMPublicKey(pq)
}
func (pk *mlkemPublicKey) KEM() KEM {
return pk.kem
}
func (pk *mlkemPublicKey) Bytes() []byte {
return pk.pq.Bytes()
}View on GitHub (pinned to b6b368adc5)
Solutions
- Construct the public key via KEM.NewPublicKey([]byte) (e.g. MLKEM768.NewPublicKey) which yields the correct wrapped type.
- Ensure pub is produced by mlkem.NewEncapsulationKey768 or mlkem.NewEncapsulationKey1024.
- Type-assert pub to one of the two supported concrete types before calling NewMLKEMPublicKey.
Example fix
// before pub, err := hpke.NewMLKEMPublicKey(customEncapsulator) // unsupported // after ek, _ := mlkem.NewEncapsulationKey768(rawKeyBytes) pub, err := hpke.NewMLKEMPublicKey(ek)
Defensive patterns
Strategy: type-guard
Validate before calling
func isValidMLKEMPub(pub crypto.Encapsulator) bool {
switch pub.(type) {
case *mlkem.EncapsulationKey768, *mlkem.EncapsulationKey1024:
return true
}
return false
} Type guard
func mlkemPubKind(pub crypto.Encapsulator) string {
switch pub.(type) {
case *mlkem.EncapsulationKey768:
return "768"
case *mlkem.EncapsulationKey1024:
return "1024"
}
return "unsupported"
} Prevention
- Prefer KEM.NewPublicKey([]byte) over NewMLKEMPublicKey for raw bytes.
- Build encapsulators only via mlkem.NewEncapsulationKey768/1024.
- Reject generic Encapsulator inputs at your API boundary.
When it happens
Trigger: Calling NewMLKEMPublicKey(pub) where pub is an Encapsulator of an unrecognized concrete type — e.g. a mock/test double, a custom KEM implementation, or a future ML-KEM variant not yet wrapped here.
Common situations: Unit tests passing a fake Encapsulator; integrating an alternate PQ KEM library whose type does not match the mlkem wrappers; protocol code that accepts a generic crypto.Encapsulator and forwards it here.
Related errors
- invalid encapsulated key size
- unsupported KEM
- invalid public key size
- hpke: invalid hybrid KEM secret length
- private key seed not available
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/b9303f2869a24b15.
Report an issue: GitHub.