apache/iceberg · error · RuntimeIOException

Failed to create GCP cloud KMS service client

Error message

Failed to create GCP cloud KMS service client

What it means

GcpKeyManagementClient lazily creates a Google Cloud KeyManagementServiceClient. If client construction throws IOException (credential resolution, endpoint reachability, environment problems), it is wrapped in RuntimeIOException('Failed to create GCP cloud KMS service client').

Source

Thrown at gcp/src/main/java/org/apache/iceberg/gcp/GcpKeyManagementClient.java:123

    if (kmsClient == null) {
      synchronized (this) {
        if (kmsClient == null) {
          GCPProperties gcpProperties = new GCPProperties(allProperties);
          try {
            KeyManagementServiceSettings.Builder kmsBuilder =
                KeyManagementServiceSettings.newBuilder();
            if (gcpProperties.oauth2Token().isPresent()) {
              OAuth2Credentials oAuth2Credentials =
                  GCPAuthUtils.oauth2CredentialsFromGcpProperties(gcpProperties, closeableGroup);
              kmsBuilder.setCredentialsProvider(FixedCredentialsProvider.create(oAuth2Credentials));
            }

            // if not OAuth then defaults to GoogleCredentials.getApplicationDefault()
            this.kmsClient = KeyManagementServiceClient.create(kmsBuilder.build());
            closeableGroup.addCloseable(kmsClient);

          } catch (IOException e) {
            throw new RuntimeIOException(e, "Failed to create GCP cloud KMS service client");
          }
        }
      }
    }
    return kmsClient;
  }

  private static final class ByteStringShim {
    private static final String ORIGINAL_BYTE_STRING_CLASS_NAME = "com.google.protobuf.ByteString";
    private static final String SHADED_BYTE_STRING_CLASS_NAME =
        "org.apache.iceberg.gcp.shaded." + ORIGINAL_BYTE_STRING_CLASS_NAME;
    private static final Class<?> BYTE_STRING_CLASS;

    static {
      Class<?> byteStringClass =
          DynClasses.builder().impl(SHADED_BYTE_STRING_CLASS_NAME).orNull().build();
      if (byteStringClass == null) {
        byteStringClass = DynClasses.builder().impl(ORIGINAL_BYTE_STRING_CLASS_NAME).build();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify credentials are resolvable: GOOGLE_APPLICATION_CREDENTIALS set to a valid service-account JSON or ADC configured via gcloud auth application-default login
  2. Confirm workload identity / service account attachment on GKE/Cloud Run/Compute
  3. Check network egress to cloudkms.googleapis.com (proxies, VPC-SC, private Google access)
  4. Validate the credentials file JSON and scopes before startup

Example fix

// before
// no credential setup; client created lazily and fails at first use
// after
// fail fast at startup
GoogleAuthManager auth = ...; auth.initialize(properties); // validates credentials early
KmsClient client = new GcpKeyManagementClient(properties).kmsClient();
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: can ADC resolve credentials?
try { GoogleCredentials.getApplicationDefault().createScoped("https://www.googleapis.com/auth/cloud-platform"); } catch (IOException e) { throw new IllegalStateException("No GCP credentials configured", e); }

Try / catch

try { client.kmsClient(); } catch (RuntimeIOException e) { LOG.error("KMS client init failed — check GCP credentials/network", e); throw e; }

Prevention

When it happens

Trigger: First call to kmsClient() when KeyManagementServiceClient.create fails — typically Application Default Credentials are unavailable, the credentials file is missing/invalid, or the GCP KMS endpoint cannot be reached.

Common situations: Missing GOOGLE_APPLICATION_CREDENTIALS env var, workload identity not configured on the compute environment, private network without access to googleapis.com, or malformed gcp credentials JSON.

Related errors


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