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

  1. 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`).
  2. Request a fresh token from the node and retry; the timestamp is signed so it cannot be refreshed client-side.
  3. 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).
  4. 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

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


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