kubernetes/kops · error
EK public key is %T, expected *rsa.PublickKey
Error message
EK public key is %T, expected *rsa.PublickKey
What it means
The EkPub parsed successfully but is not an RSA public key (e.g. ECDSA), while verifySignature expects *rsa.PublicKey. The verifier rejects keys of any other type. Note the message contains a typo: "PublickKey".
Source
Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:230
if err != nil {
return nil, fmt.Errorf("failed to get shield instance identity: %w", err)
}
if response.SigningKey == nil {
return nil, fmt.Errorf("instance doesn't have a signing key in ShieldedVmIdentity")
}
block, _ := pem.Decode([]byte(response.SigningKey.EkPub))
if block == nil {
return nil, fmt.Errorf("failed parsing PEM block from EkPub %q", response.SigningKey.EkPub)
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, fmt.Errorf("failed parsing EK public key: %w", err)
}
rsaPub, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("EK public key is %T, expected *rsa.PublickKey", pub)
}
return rsaPub, nil
}
// GetInstanceCertificateAlternateNames returns the instance hostname and addresses that should go into certificates.
// The first value is the node name and any additional values are IP addresses.
func GetInstanceCertificateAlternateNames(instance *compute.Instance) ([]string, error) {
var sans []string
for _, iface := range instance.NetworkInterfaces {
if iface.NetworkIP != "" {
sans = append(sans, iface.NetworkIP)
}
if iface.Ipv6Address != "" {
sans = append(sans, iface.Ipv6Address)
}
// We only use data for the first interface, and only the first IP
if len(sans) > 0 {View on GitHub (pinned to 4c8573c808)
Solutions
- Confirm the instance's vTPM EK algorithm is RSA (2048) and recreate it if not
- Check GCE/SDK updates that might alter the key type and update the verifier to support additional key types
- Upgrade kops so the verifier matches current GCE behavior
Defensive patterns
Strategy: type-guard
Validate before calling
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil { return err }
if _, ok := pub.(*rsa.PublicKey); !ok {
return fmt.Errorf("instance EK key is %T; verifier requires RSA", pub)
} Type guard
func isRSAPublicKey(pub crypto.PublicKey) (*rsa.PublicKey, bool) {
rsaPub, ok := pub.(*rsa.PublicKey)
return rsaPub, ok
} Try / catch
rsaPub, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("EK public key is %T, expected *rsa.PublicKey", pub)
} Prevention
- Provision nodes with RSA (2048) vTPM EK
- Extend the verifier to support additional key types if GCE offers them
- Keep kops upgraded to track GCE identity changes
When it happens
Trigger: type assertion pub.(*rsa.PublicKey) fails because the Shielded VM identity's EK key is of a non-RSA type.
Common situations: GCE changing or configuring EK key algorithms; instance generating an EC-based EK; future API/SDK behavior changes.
Related errors
- failed to get GCE RSA attestation key from TPM: %w
- failed to marshal token data: %w
- failed to marshal token: %w
- decoding authorization token: %w
- unmarshalling authorization token: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b39218acdcf42fb9.
Report an issue: GitHub.