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

AwsClientProperties.credentialsProvider attempts to load a user-supplied AwsCredentialsProvider implementation class by name via DynClasses. If the class is not on the classpath, ClassNotFoundException is wrapped and rethrown as this IllegalArgumentException. It exists so that custom credential providers can be plugged in by fully-qualified class name.

Source

Thrown at aws/src/main/java/org/apache/iceberg/aws/AwsClientProperties.java:283

   * <p>Sample usage:
   *
   * <pre>
   *     S3Client.builder().applyMutation(awsClientProperties::applyLegacyMd5Plugin)
   * </pre>
   */
  public <BuilderT extends AwsClientBuilder<BuilderT, ClientT>, ClientT> void applyLegacyMd5Plugin(
      BuilderT builder) {
    if (legacyMd5pluginEnabled) {
      builder.addPlugin(LegacyMd5Plugin.create());
    }
  }

  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()));

    try {
      return createCredentialsProvider(providerClass);
    } catch (NoSuchMethodException e) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot create an instance of %s, it does not contain a static 'create' or 'create(Map<String, String>)' method",
              credentialsProviderClass),

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the fully-qualified class name in client.credentials-provider is spelled correctly.
  2. Add the JAR containing the provider class to the runtime classpath of the application and all executors.
  3. If using the Iceberg AWS bundled runtime, confirm the provider isn't relying on an unshaded dependency; alternatively use a built-in provider (e.g. software.amazon.awssdk.auth.credentials.ContainerCredentialsProvider).

Example fix

// before
props.put("client.credentials-provider", "com.example.MyProvider"); // jar not deployed
// after
// deploy my-provider.jar alongside iceberg-aws-bundle, then
props.put("client.credentials-provider", "com.example.MyProvider");
Defensive patterns

Strategy: validation

Validate before calling

try {
  Class.forName(providerClassName, false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
  throw new IllegalStateException("Credentials provider not on classpath: " + providerClassName, e);
}

Try / catch

try {
  io = new S3FileIO(config);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Cannot load class")) {
    LOG.error("Provider class missing from classpath: check executors too");
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting client.credentials-provider (or per-client credential provider properties consumed by applyClientCredentialConfigurations) to a class name that cannot be resolved by the current classloader.

Common situations: Typo in the fully-qualified class name; the JAR containing the custom provider is missing from the runtime classpath (e.g. present in Spark job but not in the Iceberg AWS runtime or distributed to executors); shading/proguard renamed the class.

Related errors


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