apache/iceberg · error · UncheckedIOException

Failed to load Google credentials

Error message

Failed to load Google credentials

What it means

GoogleAuthManager.initialize loads Google credentials (service-account file/JSON or Application Default Credentials) and applies scopes. Any IOException during loading is wrapped in UncheckedIOException('Failed to load Google credentials').

Source

Thrown at gcp/src/main/java/org/apache/iceberg/gcp/auth/GoogleAuthManager.java:118

    try {
      if (useCredentialsPath) {
        LOG.info("Using Google credentials from path: {}", credentialsPath);
        try (FileInputStream credentialsStream = new FileInputStream(credentialsPath)) {
          this.credentials = GoogleCredentials.fromStream(credentialsStream).createScoped(scopes);
        }
      } else if (useCredentialsJson) {
        LOG.info("Using Google credentials from json");
        try (InputStream credentialsStream =
            new ByteArrayInputStream(credentialsJson.getBytes(StandardCharsets.UTF_8))) {
          this.credentials = GoogleCredentials.fromStream(credentialsStream).createScoped(scopes);
        }
      } else {
        LOG.info("Using Application Default Credentials with scopes: {}", scopesString);
        this.credentials = GoogleCredentials.getApplicationDefault().createScoped(scopes);
      }
    } catch (IOException e) {
      throw new UncheckedIOException("Failed to load Google credentials", e);
    }

    this.initialized = true;
  }

  /**
   * Initializes and returns a short-lived session, typically for fetching configuration. This
   * implementation reuses the long-lived catalog session logic.
   */
  @Override
  public AuthSession initSession(RESTClient initClient, Map<String, String> properties) {
    return catalogSession(initClient, properties);
  }

  /**
   * Returns a long-lived session tied to the catalog's lifecycle. This session uses Google
   * Application Default Credentials or a specified service account.
   *

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the credentials file path exists and is readable from the process, or that ADC is configured (gcloud auth application-default login / GOOGLE_APPLICATION_CREDENTIALS)
  2. Validate the service-account JSON is well-formed and the key is not revoked
  3. On GCP infra, attach a service account / enable workload identity instead of shipping key files
  4. Pre-flight credentials at startup so this surfaces before query time

Example fix

// before
String path = properties.get("gcp.credentials-path"); // file may not exist
// after
String path = properties.get("gcp.credentials-path");
if (path != null && !Files.isReadable(Path.of(path))) {
  throw new IllegalArgumentException("Credentials file not readable: " + path);
}
Defensive patterns

Strategy: try-catch

Validate before calling

String path = props.get("gcp.credentials-path");
if (path != null && !Files.isReadable(Path.of(path))) { throw new IllegalArgumentException("Unreadable credentials file: " + path); }

Try / catch

try { authManager.initialize(props); } catch (UncheckedIOException e) { LOG.error("Google credential load failed", e.getCause()); throw e; }

Prevention

When it happens

Trigger: initialize() runs when the credentials file at GCP_CREDENTIALS_PATH_PROPERTY does not exist or is unreadable, the JSON is invalid, or GoogleCredentials.getApplicationDefault() finds no credential source.

Common situations: Wrong/relative path to the service-account key, file permissions, missing GOOGLE_APPLICATION_CREDENTIALS in the runtime container, or no workload identity on GKE.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/2ab338265ad32b27. Report an issue: GitHub.