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').

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.

Appendix: 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)