{"record":{"id":"5a92d22681fdc16c","repo":"kubernetes/kops","slug":"failed-to-sign-token-data-w-5a92d2","errorCode":null,"errorMessage":"failed to sign token data: %w","messagePattern":"failed to sign token data: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpmauthenticator.go","lineNumber":103,"sourceCode":"\tklog.Infof(\"TPM initialization took %v\", time.Since(tpmStart))\n\n\tdata := gcetpm.AuthTokenData{\n\t\tGCPProjectID: a.projectID,\n\t\tZone:         a.zone,\n\t\tInstance:     a.instance,\n\t\tTimestamp:    time.Now().Unix(),\n\t\tAudience:     gcetpm.AudienceNodeAuthentication,\n\t\tRequestHash:  requestHash[:],\n\t}\n\n\tpayload, err := json.Marshal(&data)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to marshal token data: %w\", err)\n\t}\n\n\tsignature, err := tpmSign(key, payload)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to sign token data: %w\", err)\n\t}\n\ttoken := &gcetpm.AuthToken{\n\t\tData:      payload,\n\t\tSignature: signature,\n\t}\n\n\tb, err := json.Marshal(token)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to marshal token: %w\", err)\n\t}\n\treturn gcetpm.GCETPMAuthenticationTokenPrefix + base64.StdEncoding.EncodeToString(b), nil\n}\n\n// tpmSign performs a TPM signature with the tpmKey, and sanity checks the result.\nfunc tpmSign(tpmKey *client.Key, payload []byte) ([]byte, error) {\n\tbeforeSign := time.Now()\n\tsignature, err := tpmKey.SignData(payload)\n\tif err != nil {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpmauthenticator.go#L85-L121","documentation":"CreateToken signs the marshalled token payload with the TPM key via tpmSign. If tpmKey.SignData fails, the error is wrapped as 'failed to sign token data'. This means the TPM refused or failed the signing operation even though the key was successfully loaded.","triggerScenarios":"tpmSign(key, payload) -> client.Key.SignData(payload) returns an error: transient TPM communication failure, session/handle exhaustion, or a key usage/policy restriction.","commonSituations":"TPM busy or wedged under concurrent access by multiple node components; TPM lockout after failed auth attempts; payload/padding scheme mismatch; device I/O timeouts.","solutions":["Retry the token creation — TPM transient failures are often temporary","Check for TPM lockout state and reset if locked (tpm2_getcap / vendor tools)","Reduce concurrent TPM access on the node (single signer path)","Check dmesg/journal for tpm_crb or tpm_tis I/O errors indicating hardware/driver problems","Replace the instance if the TPM hardware is persistently failing"],"exampleFix":"null","handlingStrategy":"retry","validationCode":"// pre-check TPM responsiveness\nopened, err := tpm2.OpenTPM(\"/dev/tpmrm0\")\nif err != nil { return fmt.Errorf(\"TPM not responding: %w\", err) }\nopened.Close()","typeGuard":null,"tryCatchPattern":"token, err := authenticator.CreateToken(ctx, request)\nif err != nil && strings.Contains(err.Error(), \"failed to sign token data\") {\n    // retry with backoff; TPM transient failures are common\n    time.Sleep(backoff)\n    return authenticator.CreateToken(ctx, request)\n}","preventionTips":["Serialize TPM access on the node (avoid many concurrent signers)","Monitor dmesg for TPM I/O errors","Set reasonable TPM retry limits before failing the node","Keep the node's go-attestation version aligned with kops"],"tags":["gcp","tpm","signing","crypto"],"backgroundTag":"tpm-sign-operation-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}