{"record":{"id":"599dd221bebe1899","repo":"apache/iceberg","slug":"failed-to-obtain-google-access-token-cannot-authe","errorCode":null,"errorMessage":"Failed to obtain Google access token. Cannot authenticate request.","messagePattern":"Failed to obtain Google access token\\. Cannot authenticate request\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"gcp/src/main/java/org/apache/iceberg/gcp/auth/GoogleAuthSession.java","lineNumber":77,"sourceCode":"  @Override\n  public HTTPRequest authenticate(HTTPRequest request) {\n    try {\n      credentials.refreshIfExpired();\n      AccessToken token = credentials.getAccessToken();\n\n      if (token != null && token.getTokenValue() != null) {\n        HTTPHeaders newHeaders =\n            request\n                .headers()\n                .putIfAbsent(\n                    HTTPHeaders.of(\n                        HTTPHeaders.HTTPHeader.of(\n                            \"Authorization\", \"Bearer \" + token.getTokenValue())));\n        return newHeaders.equals(request.headers())\n            ? request\n            : ImmutableHTTPRequest.builder().from(request).headers(newHeaders).build();\n      } else {\n        throw new IllegalStateException(\n            \"Failed to obtain Google access token. Cannot authenticate request.\");\n      }\n    } catch (IOException e) {\n      LOG.error(\"IOException while trying to refresh Google access token\", e);\n      throw new UncheckedIOException(\"Failed to refresh Google access token\", e);\n    }\n  }\n\n  /**\n   * Closes the session. This is a no-op for GoogleAuthSession as the lifecycle of GoogleCredentials\n   * is not managed by this session.\n   */\n  @Override\n  public void close() {\n    // No-op\n  }\n}\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/gcp/src/main/java/org/apache/iceberg/gcp/auth/GoogleAuthSession.java#L59-L95","documentation":"GoogleAuthSession.authenticate adds a Bearer token to outgoing requests. If the refreshed credentials yield no token (token blocking returns null/absent), it throws IllegalStateException('Failed to obtain Google access token. Cannot authenticate request.') because the request cannot be authorized.","triggerScenarios":"authenticate(request) is called but credentials.refreshIfExpired()/getToken() produces no usable AccessToken — e.g. credentials never initialized, refresh silently skipped, or the credential instance cannot block for a token.","commonSituations":"Clock skew on the client machine, credentials object constructed without scopes required by the API, or a session used before GoogleAuthManager.initialize completed.","solutions":["Ensure initialize() ran and credentials have the required scopes before authenticating requests","Force a refresh and check token expiry: credentials.refreshIfExpired() then assert getAccessToken() != null","Check system clock skew (NTP) which can invalidate cached tokens","Replace the session/credentials object if it is in a permanently unauthenticated state"],"exampleFix":"// before\nCredentials creds = GoogleCredentials.getApplicationDefault(); // no scopes\n// after\nCredentials creds = GoogleCredentials.getApplicationDefault().createScoped(requiredScopes);\ncreds.refreshIfExpired();\nPreconditions.checkState(creds.getAccessToken() != null, \"No access token\");","handlingStrategy":"try-catch","validationCode":"if (credentials.getAccessToken() == null || isExpired(credentials.getAccessToken())) { credentials.refreshIfExpired(); }\nif (credentials.getAccessToken() == null) { throw new IllegalStateException(\"Token unavailable before request\"); }","typeGuard":null,"tryCatchPattern":"try { request = session.authenticate(request); } catch (IllegalStateException e) { LOG.error(\"No Google access token — re-initialize session\", e); throw e; }","preventionTips":["Always create credentials with required scopes","Sync system clock (NTP) to avoid token expiry issues","Initialize sessions before first request, not lazily"],"tags":["gcp","authentication","token","state"],"backgroundTag":"oauth-token-exchange-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}