apache/iceberg · error · IllegalArgumentException

Cannot initialize S3FileIOAwsClientFactory, %s does not impl

Error message

Cannot initialize S3FileIOAwsClientFactory, %s does not implement S3FileIOAwsClientFactory.

What it means

S3FileIOawsClientFactories.load() loads a user-configured factory class (via the `s3.io-aws.client-factory-impl` property) and reflectively instantiates it. After construction the result is cast to S3FileIOAwsClientFactory; if the configured class does not implement that interface, the ClassCastException is rethrown as this IllegalArgumentException. This guards the S3FileIO against custom client factories of the wrong type.

Source

Thrown at aws/src/main/java/org/apache/iceberg/aws/S3FileIOAwsClientFactories.java:70

    DynConstructors.Ctor<S3FileIOAwsClientFactory> ctor;
    try {
      ctor =
          DynConstructors.builder(S3FileIOAwsClientFactory.class)
              .loader(S3FileIOAwsClientFactories.class.getClassLoader())
              .hiddenImpl(impl)
              .buildChecked();
    } catch (NoSuchMethodException e) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot initialize S3FileIOAwsClientFactory, missing no-arg constructor: %s", impl),
          e);
    }

    S3FileIOAwsClientFactory factory;
    try {
      factory = ctor.newInstance();
    } catch (ClassCastException e) {
      throw new IllegalArgumentException(
          String.format(
              "Cannot initialize S3FileIOAwsClientFactory, %s does not implement S3FileIOAwsClientFactory.",
              impl),
          e);
    }

    factory.initialize(properties);
    return factory;
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Make the configured class implement org.apache.iceberg.aws.S3FileIOAwsClientFactory (and its initialize(Map) method).
  2. Check the `s3.io-aws.client-factory-impl` property value for typos or pointing at the wrong class (e.g. a DynamoDbFileIOAwsClientFactory).
  3. Verify the Iceberg AWS dependency version used to compile the custom factory matches the runtime version, since the interface may have changed.

Example fix

// before
props.put("s3.io-aws.client-factory-impl", "com.example.MyCustomFactory"); // MyCustomFactory implements AwsClientFactory
class MyCustomFactory implements AwsClientFactory { ... }

// after
class MyCustomFactory implements S3FileIOAwsClientFactory {
  @Override
  public void initialize(Map<String, String> properties) { ... }
  ...
}
Defensive patterns

Strategy: try-catch

Validate before calling

Class<?> cls = Class.forName(factoryImpl);
if (!S3FileIOAwsClientFactory.class.isAssignableFrom(cls)) {
  throw new IllegalStateException(factoryImpl + " must implement S3FileIOAwsClientFactory");
}

Type guard

if (instance instanceof S3FileIOAwsClientFactory factory) { use(factory); }

Try / catch

try {
  io.initialize(props);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("does not implement S3FileIOAwsClientFactory")) {
    log.error("Check s3.io-aws.client-factory-impl: {}", props.get("s3.io-aws.client-factory-impl"), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling S3FileIO.initialize() when the property `s3.io-aws.client-factory-impl` (ClientFactory.IMPLEMENTATION) points to a class that instantiates successfully but does not implement the S3FileIOAwsClientFactory interface, causing ctor.newInstance() + implicit cast to throw ClassCastException.

Common situations: Typo pointing at a ClientFactory built for a different IO (e.g. a Glue or DynamoDb client factory class); implementing the wrong interface after an SDK refactor; a class implementing an older/renamed interface from a different Iceberg version; passing the factory's class name instead of an implementing class.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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