kubernetes/kops · error
attested document nonce mismatch: got=%q expected=%q
Error message
attested document nonce mismatch: got=%q expected=%q
What it means
Replay protection check: the nonce in the signed attested document does not match the hash derived from the HTTP request body. The document was signed for a different request (replay) or the body was altered after signing.
Source
Thrown at upup/pkg/fi/cloudup/azure/attest.go:294
// its nonce and freshness timestamps.
func parseAndValidateAttestedDocumentContent(content []byte, body []byte) (*attestedData, error) {
var data attestedData
if err := json.Unmarshal(content, &data); err != nil {
return nil, fmt.Errorf("unmarshalling attested data: %w", err)
}
klog.V(4).Infof("Attested document content: vmId=%q subscriptionId=%q createdOn=%q expiresOn=%q", data.VMId, data.SubscriptionId, data.TimeStamp.CreatedOn, data.TimeStamp.ExpiresOn)
if data.VMId == "" {
return nil, fmt.Errorf("attested document vmId is required")
}
if data.SubscriptionId == "" {
return nil, fmt.Errorf("attested document subscriptionId is required")
}
// Verify the nonce matches the request body hash (replay protection).
expectedNonce := nonceForBody(body)
if data.Nonce != expectedNonce {
return nil, fmt.Errorf("attested document nonce mismatch: got=%q expected=%q", data.Nonce, expectedNonce)
}
now := time.Now().UTC()
if data.TimeStamp.CreatedOn == "" {
return nil, fmt.Errorf("attested document createdOn is required")
}
createdOn, err := time.Parse(attestedDocumentTimeFormat, data.TimeStamp.CreatedOn)
if err != nil {
return nil, fmt.Errorf("parsing attested document creation: %w", err)
}
if createdOn.After(now.Add(attestedDocumentMaxClockSkew)) {
return nil, fmt.Errorf("attested document createdOn %s is too far in the future", data.TimeStamp.CreatedOn)
}
oldestAllowedCreatedOn := now.Add(-(attestedDocumentMaxAge + attestedDocumentMaxClockSkew))
if createdOn.Before(oldestAllowedCreatedOn) {
return nil, fmt.Errorf("attested document createdOn %s is older than allowed freshness window of %s plus %s clock skew", data.TimeStamp.CreatedOn, attestedDocumentMaxAge, attestedDocumentMaxClockSkew)
}
klog.V(4).Infof("Attested document createdOn is fresh (createdOn=%s now=%s)", createdOn.Format(time.RFC3339), now.Format(time.RFC3339))View on GitHub (pinned to 4c8573c808)
Solutions
- Reject the bootstrap request; the token is a replay or the request was tampered with
- Have the node re-request attestation so a fresh nonce-bound document is produced
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at upup/pkg/fi/cloudup/azure/attest.go:294 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/1e06d1eeb5bc6239.
Report an issue: GitHub.