kubernetes/kops · error
incorrect Timestamp %v
Error message
incorrect Timestamp %v
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:104
}
token := &gcetpm.AuthToken{}
if err = json.Unmarshal(tokenBytes, token); err != nil {
return nil, fmt.Errorf("unmarshalling authorization token: %w", err)
}
tokenData := gcetpm.AuthTokenData{}
if err := json.Unmarshal(token.Data, &tokenData); err != nil {
return nil, fmt.Errorf("unmarshalling authorization token data: %w", err)
}
// Guard against replay attacks
if tokenData.Audience != gcetpm.AudienceNodeAuthentication {
return nil, fmt.Errorf("incorrect Audience")
}
timeSkew := math.Abs(time.Since(time.Unix(tokenData.Timestamp, 0)).Seconds())
if timeSkew > float64(v.opt.MaxTimeSkew) {
return nil, fmt.Errorf("incorrect Timestamp %v", tokenData.Timestamp)
}
// Verify the token has signed the body content.
requestHash := sha256.Sum256(body)
if !bytes.Equal(requestHash[:], tokenData.RequestHash) {
return nil, fmt.Errorf("incorrect RequestHash")
}
// Some basic validation to avoid requesting invalid instances.
if tokenData.GCPProjectID == "" {
return nil, fmt.Errorf("gcpProjectID is required")
}
if tokenData.Zone == "" {
return nil, fmt.Errorf("zone is required")
}
if tokenData.Instance == "" {
return nil, fmt.Errorf("instance is required")
}View on GitHub (pinned to 4c8573c808)
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.
Example fix
// before (chrony not syncing on node) # timedatectl -> NTP: off // after # sudo systemctl enable --now chronyd && chronyc sources
Defensive patterns
Strategy: validation
Validate before calling
skew := math.Abs(time.Since(time.Unix(tokenData.Timestamp, 0)).Seconds())
if skew > maxTimeSkew {
return fmt.Errorf("token timestamp skew %.0fs exceeds allowed %.0fs; refresh token / sync NTP", skew, maxTimeSkew)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- incorrect RequestHash
- incorrect Timestamp %v
- error listing zones: %v
- failed to get GCE RSA attestation key from TPM: %w
- failed to sign token data: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/703a9d6dc75a385f.
Report an issue: GitHub.