{"record":{"id":"9edcfe5d620e804a","repo":"googleapis/mcp-toolbox","slug":"retrieved-token-is-invalid-or-expired","errorCode":null,"errorMessage":"retrieved token is invalid or expired","messagePattern":"retrieved token is invalid or expired","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/util.go","lineNumber":158,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"username from ADC cannot be an empty string\")\n\t}\n\n\treturn username, nil\n}\n\nfunc GetIAMAccessToken(ctx context.Context) (string, error) {\n\tcreds, err := google.FindDefaultCredentials(ctx, \"https://www.googleapis.com/auth/cloud-platform\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to find default credentials (run 'gcloud auth application-default login'?): %w\", err)\n\t}\n\n\ttoken, err := creds.TokenSource.Token() // This gets an oauth2.Token\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get token from token source: %w\", err)\n\t}\n\n\tif !token.Valid() {\n\t\treturn \"\", fmt.Errorf(\"retrieved token is invalid or expired\")\n\t}\n\treturn token.AccessToken, nil\n}\n","sourceCodeStart":140,"sourceCodeEnd":162,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/util.go#L140-L162","documentation":"GetIAMAccessToken validates the token returned by the TokenSource using token.Valid(), which checks that the access token is non-empty, has an expiry, and is not expired. This error means the oauth2 library handed back a token that failed those invariants — practically a bug/edge case in credential setup, such as a credentials type that yields empty access tokens.","triggerScenarios":"creds.TokenSource.Token() returns successfully but the token has an empty AccessToken, zero Expiry, or is already expired at return time — e.g. unusual/invalid credential configurations or mocked/edge-case ADC sources.","commonSituations":"ADC pointing to a key file whose token endpoint returns an empty access token; heavily skewed system clocks making the token immediately expired; using non-standard credential files hand-crafted or copied between environments.","solutions":["Re-generate credentials: 'gcloud auth application-default login' or a fresh service account key","Fix system clock synchronization (chrony/ntp)","Verify the ADC key file is a genuine, complete Google-issued credential file"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Validate token before use\nfunction tokenLooksValid(t: { access_token?: string; expiry_date?: number }): boolean {\n  return !!t.access_token && typeof t.expiry_date === \"number\" && t.expiry_date > Date.now();\n}","typeGuard":"function isUsableToken(t: { access_token: string; expiry_date?: number } | undefined | null):\n  t is { access_token: string; expiry_date?: number } {\n  return !!t && typeof t.access_token === \"string\" && t.access_token.length > 0;\n}","tryCatchPattern":"try {\n  const token = await getIAMAccessToken(ctx);\n} catch (err) {\n  if (String(err).includes(\"retrieved token is invalid or expired\")) {\n    // force-refresh credentials once, then retry\n    await refreshCredentials();\n    return getIAMAccessToken(ctx);\n  }\n  throw err;\n}","preventionTips":["Keep NTP/chrony time sync enabled; clock skew is the usual cause","Re-download ADC keys from Google rather than hand-editing them","If it recurs, request tokens through an official client library that auto-refreshes"],"tags":["google-cloud","oauth2","token","authentication"],"backgroundTag":"invalid-access-token","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}