apache/iceberg · error · IllegalArgumentException

Cannot create an instance of %s, it does not contain a stati

Error message

Cannot create an instance of %s, it does not contain a static 'create' or 'create(Map<String, String>)' method

What it means

AwsProperties.credentialsProvider instantiates the loaded provider class reflectively, first trying create(Map) then create(); if neither static factory method exists, NoSuchMethodException is wrapped as this IllegalArgumentException. Iceberg requires this convention so providers can optionally receive the configuration map.

Source

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

            "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()
                .invoke(clientCredentialsProviderProperties);
      } catch (NoSuchMethodException e) {
        provider =
            DynMethods.builder("create").hiddenImpl(providerClass).buildStaticChecked().invoke();
      }

      return provider;
    } 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),
          e);
    }
  }

  private <T extends SdkClientBuilder> void configureEndpoint(T builder, String endpoint) {
    if (endpoint != null) {
      builder.endpointOverride(URI.create(endpoint));
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Implement public static create() or public static create(Map<String, String>) in the provider class.
  2. If configuration is needed, prefer create(Map<String, String>) and read properties from the map.
  3. Alternatively wrap the class in an adapter that exposes the required static factory.

Example fix

// before
class StaticProvider implements AwsCredentialsProvider {
  StaticProvider() {}
}
// after
class StaticProvider implements AwsCredentialsProvider {
  public static AwsCredentialsProvider create(Map<String, String> properties) { return new StaticProvider(); }
}
Defensive patterns

Strategy: type-guard

Validate before calling

Class<?> c = Class.forName(providerClassName);
boolean hasFactory = java.util.Arrays.stream(c.getMethods()).anyMatch(m ->
    m.getName().equals("create") && java.lang.reflect.Modifier.isStatic(m.getModifiers()));
if (!hasFactory) throw new IllegalStateException(providerClassName + " lacks static create factory");

Type guard

static boolean hasCreateMethod(Class<?> c) {
  return java.util.Arrays.stream(c.getDeclaredMethods()).anyMatch(m ->
      m.getName().equals("create") && java.lang.reflect.Modifier.isStatic(m.getModifiers()));
}

Try / catch

try {
  s3 = new S3FileIO(config);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("'create' or 'create(Map")) {
    LOG.error("Provider {} needs a static create method", config.get("client.credentials-provider"));
  }
  throw e;
}

Prevention

When it happens

Trigger: The class configured as the credentials provider exists but defines no static create() or create(Map<String, String>) method — instantiation via DynMethods fails and this error is thrown from AwsProperties.credentialsProvider.

Common situations: Custom provider classes with only constructors; SDK-built-in providers lacking Iceberg-style create factories; accidentally deleting or renaming the create method during refactoring.

Related errors


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