kubernetes/kops · critical
failed to get GCE RSA attestation key from TPM: %w
Error message
failed to get GCE RSA attestation key from TPM: %w
What it means
CreateToken opens the node's local TPM 2.0 device and fetches the GCE RSA attestation key (EK/AIK-backed) via go-attestation's client.GceAttestationKeyRSA. If the TPM cannot provide that key (device open succeeded but key creation/loading failed), the error is wrapped with this message and CreateToken returns no token. It means node authentication via TPM attestation cannot proceed.
Source
Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpmauthenticator.go:79
zone: zone,
instance: instance,
}, nil
}
func (a *tpmAuthenticator) CreateToken(body []byte) (string, error) {
requestHash := sha256.Sum256(body)
tpmStart := time.Now()
tpmDevice, err := openTPM()
if err != nil {
return "", fmt.Errorf("failed to open TPM: %w", err)
}
defer tpmDevice.Close()
key, err := client.GceAttestationKeyRSA(tpmDevice)
if err != nil {
return "", fmt.Errorf("failed to get GCE RSA attestation key from TPM: %w", err)
}
defer key.Close()
klog.V(2).Infof("attestation key is %v", debugToPEM(key.PublicKey()))
klog.Infof("TPM initialization took %v", time.Since(tpmStart))
data := gcetpm.AuthTokenData{
GCPProjectID: a.projectID,
Zone: a.zone,
Instance: a.instance,
Timestamp: time.Now().Unix(),
Audience: gcetpm.AudienceNodeAuthentication,
RequestHash: requestHash[:],
}
payload, err := json.Marshal(&data)
if err != nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Enable Shielded VM with vTPM on the instance (or recreate the instance with shielded-secure-boot/vTPM options on)
- Ensure the process can access /dev/tpmrm0 (run privileged, add device mapping in container, check udev/permissions)
- Verify the machine actually has a TPM 2.0 device: ls /dev/tpm*
- Pin/upgrade github.com/google/go-attestation to a version compatible with your OS/GCE guest environment
- Test key availability with go-attestation tools (e.g. tpm-tools or attest client) to isolate the failing layer
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
// before creating tokens
if _, err := os.Stat("/dev/tpmrm0"); err != nil {
return fmt.Errorf("TPM device unavailable: %w", err)
} Try / catch
token, err := authenticator.CreateToken(ctx, request)
if err != nil {
if strings.Contains(err.Error(), "failed to get GCE RSA attestation key") {
// fall back to non-TPM auth or surface actionable setup error
}
return err
} Prevention
- Provision GCE nodes with Shielded VM / vTPM enabled
- Mount /dev/tpmrm0 into containers with correct permissions
- Pin go-attestation versions in go.mod and test on your node image
- Health-check TPM availability at node startup before needing tokens
When it happens
Trigger: client.GceAttestationKeyRSA(tpmDevice) returns an error: TPM lacks the GCE attestation key hierarchy, the key cannot be created/loaded, or the underlying tpm2/attestation call fails (I/O error on /dev/tpmrm0, unsupported TPM, permission denied on the device).
Common situations: Running on a GCE VM without a vTPM enabled (shielded VM / 'enableIntegrityMonitoring' off); /dev/tpmrm0 not accessible to the process (container without --device or device cgroup rules); non-GCE environment or emulated testing where the GCE-specific attestation key is absent; go-attestation version incompatibility with the guest environment.
Related errors
- creating gce IPAM controller: %w
- error building compute API client: %v
- error listing zones: %v
- unable to determine zones in region %q
- error getting ForwardingRule %q: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e8334ff3098289b5.
Report an issue: GitHub.