{"record":{"id":"0294618775f79114","repo":"kubernetes/kops","slug":"unmarshalling-authorization-token-data-w-029461","errorCode":null,"errorMessage":"unmarshalling authorization token data: %w","messagePattern":"unmarshalling authorization token data: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go","lineNumber":95,"sourceCode":"\n\tif !strings.HasPrefix(authToken, gcetpm.GCETPMAuthenticationTokenPrefix) {\n\t\treturn nil, bootstrap.ErrNotThisVerifier\n\t}\n\tauthToken = strings.TrimPrefix(authToken, gcetpm.GCETPMAuthenticationTokenPrefix)\n\n\ttokenBytes, err := base64.StdEncoding.DecodeString(authToken)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"decoding authorization token: %w\", err)\n\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.","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go#L77-L113","documentation":"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.","triggerScenarios":"json.Unmarshal(token.Data, &tokenData) fails: Data bytes are not valid JSON of AuthTokenData (fields with wrong types, empty Data, truncated inner payload).","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"tokenData := gcetpm.AuthTokenData{}\nif err := json.Unmarshal(token.Data, &tokenData); err != nil {\n    // pre-validate the inner payload before calling the verifier\n    return fmt.Errorf(\"inner token data invalid: %w\", err)\n}\nif tokenData.Audience == \"\" || tokenData.Timestamp == 0 {\n    return fmt.Errorf(\"token data missing required fields\")\n}","typeGuard":"func hasValidTokenDataShape(data []byte) bool {\n    var td gcetpm.AuthTokenData\n    if err := json.Unmarshal(data, &td); err != nil { return false }\n    return td.Audience != \"\" && td.Timestamp != 0\n}","tryCatchPattern":"token, err := verifier.VerifyToken(ctx, rawToken, request)\nif err != nil && strings.Contains(err.Error(), \"unmarshalling authorization token data\") {\n    return fmt.Errorf(\"node token schema mismatch; upgrade node: %w\", err)\n}","preventionTips":["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"],"tags":["gce","tpm","json","schema-mismatch"],"backgroundTag":"schema-validation-failed","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"}