kubernetes/kops · error

instance doesn't have a signing key in ShieldedVmIdentity

Error message

instance doesn't have a signing key in ShieldedVmIdentity

What it means

The Shielded VM identity response contained no SigningKey. GCE returns the identity structure but without a signing key when the instance is not genuinely shielded or the identity is incomplete, so the verifier cannot obtain the TPM public key to check the token signature.

Source

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

	result := &bootstrap.VerifyResult{
		NodeName:          instance.Name,
		InstanceGroupName: instanceGroupName,
		CAPIMachine:       capiMachine,
		CertificateNames:  sans,
		ChallengeEndpoint: challengeEndpoint,
	}

	return result, nil
}

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.

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Enable Shielded VM (vTPM) on the instance or its instance template/MIG
  2. Wait briefly and retry if the instance was just created
  3. Recreate the node from a shielded-VM-enabled image/template
  4. Verify with gcloud compute instances describe --format='*(shieldedInstanceConfig)' that shielded options are on

Example fix

// before
shieldedInstanceConfig:
  enableVtpm: false
// after
shieldedInstanceConfig:
  enableVtpm: true
  enableIntegrityMonitoring: true
Defensive patterns

Strategy: validation

Validate before calling

resp, err := computeClient.Instances.GetShieldedInstanceIdentity(proj, zone, name).Context(ctx).Do()
if err != nil { return err }
if resp.SigningKey == nil || resp.SigningKey.EkPub == "" {
    return errors.New("instance has no Shielded VM signing key; enable vTPM or wait for identity publication")
}

Prevention

When it happens

Trigger: GetShieldedInstanceIdentity succeeds but response.SigningKey == nil — e.g. instance created with shielded VM options disabled, or GCE hasn't populated the identity yet for a brand-new VM.

Common situations: Node template missing vTPM/shielded settings; very recently created instance queried before identity publication; custom images without shielded VM support.

Related errors


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