{"record":{"id":"703a9d6dc75a385f","repo":"kubernetes/kops","slug":"incorrect-timestamp-v-703a9d","errorCode":null,"errorMessage":"incorrect Timestamp %v","messagePattern":"incorrect Timestamp (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go","lineNumber":104,"sourceCode":"\t}\n\n\ttoken := &gcetpm.AuthToken{}\n\tif err = json.Unmarshal(tokenBytes, token); err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshalling authorization token: %w\", err)\n\t}\n\n\ttokenData := gcetpm.AuthTokenData{}\n\tif err := json.Unmarshal(token.Data, &tokenData); err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshalling authorization token data: %w\", err)\n\t}\n\n\t// Guard against replay attacks\n\tif tokenData.Audience != gcetpm.AudienceNodeAuthentication {\n\t\treturn nil, fmt.Errorf(\"incorrect Audience\")\n\t}\n\ttimeSkew := math.Abs(time.Since(time.Unix(tokenData.Timestamp, 0)).Seconds())\n\tif timeSkew > float64(v.opt.MaxTimeSkew) {\n\t\treturn nil, fmt.Errorf(\"incorrect Timestamp %v\", tokenData.Timestamp)\n\t}\n\n\t// Verify the token has signed the body content.\n\trequestHash := sha256.Sum256(body)\n\tif !bytes.Equal(requestHash[:], tokenData.RequestHash) {\n\t\treturn nil, fmt.Errorf(\"incorrect RequestHash\")\n\t}\n\n\t// Some basic validation to avoid requesting invalid instances.\n\tif tokenData.GCPProjectID == \"\" {\n\t\treturn nil, fmt.Errorf(\"gcpProjectID is required\")\n\t}\n\tif tokenData.Zone == \"\" {\n\t\treturn nil, fmt.Errorf(\"zone is required\")\n\t}\n\tif tokenData.Instance == \"\" {\n\t\treturn nil, fmt.Errorf(\"instance is required\")\n\t}","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go#L86-L122","documentation":"VerifyToken rejects the TPM-attested token because its Timestamp is too far from the verifier's current clock. The verifier computes the absolute time skew since the Unix timestamp embedded in the signed token and fails if it exceeds v.opt.MaxTimeSkew. This guard prevents replay attacks with old, previously captured tokens.","triggerScenarios":"A node presents a token whose tokenData.Timestamp, interpreted as Unix seconds, is more than MaxTimeSkew seconds away from the verifier server's wall clock at the time VerifyToken runs.","commonSituations":"Clock drift on GCE VMs (NTP disabled or broken), an old/cached token reused after its window expired, replayed captured tokens, or verifier/node clock skew after VM live-migration or suspend.","solutions":["Ensure NTP is running and synchronized on both the node VM and the verifier host (e.g. `chrony` / Google's NTP server `metadata.google.internal`).","Request a fresh token from the node and retry; the timestamp is signed so it cannot be refreshed client-side.","Increase MaxTimeSkew in the verifier options if legitimate clock skew in your environment exceeds the current setting (do this cautiously — it widens the replay window).","Verify the node is generating the token with the correct unit (Unix seconds) timestamp format."],"exampleFix":"// before (chrony not syncing on node)\n# timedatectl  -> NTP: off\n// after\n# sudo systemctl enable --now chronyd && chronyc sources","handlingStrategy":"validation","validationCode":"skew := math.Abs(time.Since(time.Unix(tokenData.Timestamp, 0)).Seconds())\nif skew > maxTimeSkew {\n\treturn fmt.Errorf(\"token timestamp skew %.0fs exceeds allowed %.0fs; refresh token / sync NTP\", skew, maxTimeSkew)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run NTP (chrony/systemd-timesyncd) on all nodes and verifier hosts","Always request a fresh token per request; never cache attestation tokens","Keep client and verifier MaxTimeSkew conventions aligned","Alert on clock-skew metrics in the cluster"],"tags":["gcp","tpm","authentication","clock-skew"],"backgroundTag":"jwt-token-expired","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"}