kubernetes/kops · error
unmarshalling authorization token data: %w
Error message
unmarshalling authorization token data: %w
What it means
VerifyToken then unmarshals the inner Data field into gcetpm.AuthTokenData. Failure means the outer token was fine but the signed payload is not the expected structure, so verification must abort before checking audience/timestamp/signature.
Source
Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:95
if !strings.HasPrefix(authToken, gcetpm.GCETPMAuthenticationTokenPrefix) {
return nil, bootstrap.ErrNotThisVerifier
}
authToken = strings.TrimPrefix(authToken, gcetpm.GCETPMAuthenticationTokenPrefix)
tokenBytes, err := base64.StdEncoding.DecodeString(authToken)
if err != nil {
return nil, fmt.Errorf("decoding authorization token: %w", err)
}
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.View on GitHub (pinned to 4c8573c808)
Solutions
- Align versions of the node signer and verifier so AuthTokenData schema matches
- Decode the token (base64 -d then jq) and inspect the inner Data structure
- Regenerate the token from the current node binary
- Roll back a control-plane upgrade that changed gcetpm token format
Defensive patterns
Strategy: validation
Validate before calling
tokenData := gcetpm.AuthTokenData{}
if err := json.Unmarshal(token.Data, &tokenData); err != nil {
// pre-validate the inner payload before calling the verifier
return fmt.Errorf("inner token data invalid: %w", err)
}
if tokenData.Audience == "" || tokenData.Timestamp == 0 {
return fmt.Errorf("token data missing required fields")
} Type guard
func hasValidTokenDataShape(data []byte) bool {
var td gcetpm.AuthTokenData
if err := json.Unmarshal(data, &td); err != nil { return false }
return td.Audience != "" && td.Timestamp != 0
} Try / catch
token, err := verifier.VerifyToken(ctx, rawToken, request)
if err != nil && strings.Contains(err.Error(), "unmarshalling authorization token data") {
return fmt.Errorf("node token schema mismatch; upgrade node: %w", err)
} Prevention
- Keep AuthTokenData schema stable; version the token format if it must change
- Roll node and control-plane upgrades together
- Log the decoded payload (at low verbosity) when schema errors occur
When it happens
Trigger: json.Unmarshal(token.Data, &tokenData) fails: Data bytes are not valid JSON of AuthTokenData (fields with wrong types, empty Data, truncated inner payload).
Common situations: Version skew where AuthTokenData fields were renamed/retyped between signer and verifier; token produced by an older kops release against a newer control-plane; corrupted or hand-crafted tokens.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- failed to marshal token data: %w
- failed to marshal token: %w
- unmarshalling authorization token: %w
- failed to get GCE RSA attestation key from TPM: %w
- decoding authorization token: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/0294618775f79114.
Report an issue: GitHub.