apache/iceberg · error · IllegalArgumentException

Cannot load class %s, it does not exist in the classpath

Error message

Cannot load class %s, it does not exist in the classpath

What it means

AwsProperties.credentialsProvider loads a user-configured AwsCredentialsProvider class by name via DynClasses; if the class is absent from the classpath it throws this IllegalArgumentException wrapping the ClassNotFoundException. This is the legacy AwsProperties path (as opposed to AwsClientProperties) for pluggable credential providers.

Source

Thrown at aws/src/main/java/org/apache/iceberg/aws/AwsProperties.java:567

    String sessionName =
        this.clientAssumeRoleSessionName != null
            ? this.clientAssumeRoleSessionName
            : String.format("iceberg-aws-%s", uuid);
    return AssumeRoleRequest.builder()
        .roleArn(this.clientAssumeRoleArn)
        .roleSessionName(sessionName)
        .durationSeconds(this.clientAssumeRoleTimeoutSec)
        .externalId(this.clientAssumeRoleExternalId)
        .tags(this.stsClientAssumeRoleTags)
        .build();
  }

  private AwsCredentialsProvider credentialsProvider(String credentialsProviderClass) {
    Class<?> providerClass;
    try {
      providerClass = DynClasses.builder().impl(credentialsProviderClass).buildChecked();
    } catch (ClassNotFoundException e) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot load class %s, it does not exist in the classpath", credentialsProviderClass),
          e);
    }

    Preconditions.checkArgument(
        AwsCredentialsProvider.class.isAssignableFrom(providerClass),
        String.format(
            "Cannot initialize %s, it does not implement %s.",
            credentialsProviderClass, AwsCredentialsProvider.class.getName()));

    AwsCredentialsProvider provider;
    try {
      try {
        provider =
            DynMethods.builder("create")
                .hiddenImpl(providerClass, Map.class)
                .buildStaticChecked()

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Correct the class name in the credentials-provider property.
  2. Add the provider's JAR to the runtime classpath visible to the code creating AwsProperties.
  3. Fall back to a default provider (e.g. software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider) if a custom one is not actually required.

Example fix

// before
props.put("client.credentials-provider", "com.example.MyCredsProvider");
// after (corrected name and deployed jar)
props.put("client.credentials-provider", "com.example.creds.MyCredsProvider");
Defensive patterns

Strategy: validation

Validate before calling

try {
  Class.forName(providerClassName, false, AwsProperties.class.getClassLoader());
} catch (ClassNotFoundException e) {
  throw new IllegalStateException("Provider class not resolvable: " + providerClassName, e);
}

Try / catch

try {
  props = new AwsProperties(config);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Cannot load class")) {
    LOG.error("Check class name and runtime classpath for: {}", config.get("client.credentials-provider"));
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting s3.windower... no — specifically setting the credentials-provider class property consumed by AwsProperties.credentialsProvider (e.g. client.credentials-provider for S3FileIO via AwsProperties) to a class name unresolvable by the classloader.

Common situations: Misspelled fully-qualified class name; custom provider JAR not shipped to driver/executors; class present in a different classloader (e.g. Spark cluster mode) than the one DynClasses uses; migration from one runtime bundle to another dropping a dependency.

Related errors


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