kubernetes/kops · error

failed parsing EK public key

Error message

failed parsing EK public key: %w

What it means

Wraps rsa/x509 parsing failure of the endorsement (EK) public key in the GCE TPM verifier: the PEM-decoded signing key block could not be parsed into an RSA public key. Indicates the Shielded Instance Identity API returned an unexpected EkPub format.

Solutions

  1. Verify the instance's Shielded VM identity is healthy in GCP
  2. Retry the verification in case of a malformed transient response
  3. Report if the EkPub format is consistently unparseable (possible API change)
Defensive patterns

Strategy: try-catch

Validate before calling

pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
    return fmt.Errorf("EkPub is not a valid SPKI public key: %w", err) // surface before verification
}

Try / catch

if _, err := x509.ParsePKIXPublicKey(block.Bytes); err != nil {
    log.Warn("bad EK key from GCE identity; refetching")
    resp, rerr := refetchIdentity(ctx)
    if rerr != nil { return rerr }
    // retry parse once, then fail
}

Prevention

When it happens

Trigger: x509.ParsePKIXPublicKey(block.Bytes) returns an error after successful PEM decode — DER bytes inside the PEM don't form a valid SubjectPublicKeyInfo.

Common situations: Unexpected key encoding returned by the GCE identity API; corrupted/truncated response; custom signing key material injected by unusual instance configuration.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/15a65e343fa2e05a. Report an issue: GitHub.

Appendix: source

Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:226

}

func (v *tpmVerifier) getTPMSigningKey(ctx context.Context, data *gcetpm.AuthTokenData) (*rsa.PublicKey, error) {
	response, err := v.computeClient.Instances.GetShieldedInstanceIdentity(data.GCPProjectID, data.Zone, data.Instance).Context(ctx).Do()
	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 != "" {

View on GitHub (pinned to 4c8573c808)