apache/iceberg · error · IllegalStateException
Failed to obtain Google access token. Cannot authenticate re
Error message
Failed to obtain Google access token. Cannot authenticate request.
What it means
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.
Source
Thrown at gcp/src/main/java/org/apache/iceberg/gcp/auth/GoogleAuthSession.java:77
@Override
public HTTPRequest authenticate(HTTPRequest request) {
try {
credentials.refreshIfExpired();
AccessToken token = credentials.getAccessToken();
if (token != null && token.getTokenValue() != null) {
HTTPHeaders newHeaders =
request
.headers()
.putIfAbsent(
HTTPHeaders.of(
HTTPHeaders.HTTPHeader.of(
"Authorization", "Bearer " + token.getTokenValue())));
return newHeaders.equals(request.headers())
? request
: ImmutableHTTPRequest.builder().from(request).headers(newHeaders).build();
} else {
throw new IllegalStateException(
"Failed to obtain Google access token. Cannot authenticate request.");
}
} catch (IOException e) {
LOG.error("IOException while trying to refresh Google access token", e);
throw new UncheckedIOException("Failed to refresh Google access token", e);
}
}
/**
* Closes the session. This is a no-op for GoogleAuthSession as the lifecycle of GoogleCredentials
* is not managed by this session.
*/
@Override
public void close() {
// No-op
}
}
View on GitHub (pinned to 86d9c8fc54)
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
Example fix
// before Credentials creds = GoogleCredentials.getApplicationDefault(); // no scopes // after Credentials creds = GoogleCredentials.getApplicationDefault().createScoped(requiredScopes); creds.refreshIfExpired(); Preconditions.checkState(creds.getAccessToken() != null, "No access token");
Defensive patterns
Strategy: try-catch
Validate before calling
if (credentials.getAccessToken() == null || isExpired(credentials.getAccessToken())) { credentials.refreshIfExpired(); }
if (credentials.getAccessToken() == null) { throw new IllegalStateException("Token unavailable before request"); } Try / catch
try { request = session.authenticate(request); } catch (IllegalStateException e) { LOG.error("No Google access token — re-initialize session", e); throw e; } Prevention
- Always create credentials with required scopes
- Sync system clock (NTP) to avoid token expiry issues
- Initialize sessions before first request, not lazily
When it happens
Trigger: 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.
Common situations: Clock skew on the client machine, credentials object constructed without scopes required by the API, or a session used before GoogleAuthManager.initialize completed.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Failed to refresh Google access token
- Failed to get application default credentials
- Failed to create impersonated credentials for ${impersonateS
- Cannot specify both %s and %s
- Failed to load Google credentials
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/599dd221bebe1899.
Report an issue: GitHub.