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

  1. Construct the public key via KEM.NewPublicKey([]byte) (e.g. MLKEM768.NewPublicKey) which yields the correct wrapped type.
  2. Ensure pub is produced by mlkem.NewEncapsulationKey768 or mlkem.NewEncapsulationKey1024.
  3. 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

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


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