apache/iceberg · error · IllegalArgumentException

Cannot initialize Catalog implementation %s: %s

Error message

Cannot initialize Catalog implementation %s: %s

What it means

Thrown by CatalogUtil.loadCatalog when the given catalog implementation class name cannot be resolved to a class with a usable no-arg constructor (the class is not on the classpath or has no suitable constructor). DynConstructors.buildChecked() raises NoSuchMethodException, which is wrapped in this IllegalArgumentException with the original cause attached.

Source

Thrown at core/src/main/java/org/apache/iceberg/CatalogUtil.java:279

   * <p>The catalog must have a no-arg constructor. If the class implements Configurable, a Hadoop
   * config will be passed using Configurable.setConf. {@link Catalog#initialize(String catalogName,
   * Map options)} is called to complete the initialization.
   *
   * @param impl catalog implementation full class name
   * @param catalogName catalog name
   * @param properties catalog properties
   * @param hadoopConf hadoop configuration if needed
   * @return initialized catalog object
   * @throws IllegalArgumentException if no-arg constructor not found or error during initialization
   */
  public static Catalog loadCatalog(
      String impl, String catalogName, Map<String, String> properties, Object hadoopConf) {
    Preconditions.checkNotNull(impl, "Cannot initialize custom Catalog, impl class name is null");
    DynConstructors.Ctor<Catalog> ctor;
    try {
      ctor = DynConstructors.builder(Catalog.class).impl(impl).buildChecked();
    } catch (NoSuchMethodException e) {
      throw new IllegalArgumentException(
          String.format("Cannot initialize Catalog implementation %s: %s", impl, e.getMessage()),
          e);
    }

    Catalog catalog;
    try {
      catalog = ctor.newInstance();

    } catch (ClassCastException e) {
      throw new IllegalArgumentException(
          String.format("Cannot initialize Catalog, %s does not implement Catalog.", impl), e);
    }

    configureHadoopConf(catalog, hadoopConf);

    catalog.initialize(catalogName, properties);
    return catalog;
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the class name in the catalog-impl property is spelled correctly and fully qualified (e.g. org.apache.iceberg.rest.RESTCatalog).
  2. Add the Iceberg runtime/connector JAR containing the class to the application classpath (e.g. iceberg-aws-bundle, iceberg-gcp-bundle, iceberg-nessie).
  3. Check that the class is public and declares a public no-arg constructor; add one or use a different implementation.
  4. Confirm the Iceberg version of the runtime JARs matches the version the class name was written for (classes move between versions).

Example fix

// before
Map<String, String> opts = Map.of("type", "jdbc"); // JAR missing -> NoSuchMethodException for JDBC catalog
// after
// add iceberg-jdbc (or the bundle jar) to the classpath, or use an available type:
Map<String, String> opts = Map.of("type", "hadoop");
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  Class<?> cls = Class.forName(implClassName, true, Thread.currentThread().getContextClassLoader());
  if (!org.apache.iceberg.Catalog.class.isAssignableFrom(cls) || cls.getConstructor() == null) {
    throw new IllegalStateException(implClassName + " missing or lacks public no-arg constructor");
  }
} catch (ClassNotFoundException e) {
  throw new IllegalStateException("Catalog class not on classpath: " + implClassName, e);
}

Type guard

static boolean isLoadableCatalog(String impl) {
  try {
    Class<?> cls = Class.forName(impl);
    return Catalog.class.isAssignableFrom(cls);
  } catch (ClassNotFoundException | NoClassDefFoundError e) {
    return false;
  }
}

Try / catch

try {
  Catalog catalog = CatalogUtil.loadCatalog(impl, name, props, hadoopConf);
} catch (IllegalArgumentException e) {
  LOG.error("Failed to load catalog impl {} (check classpath/bundle jars): {}", impl, e.getMessage(), e);
  throw e; // config error is not recoverable
}

Prevention

When it happens

Trigger: Calling CatalogUtil.loadCatalog(impl, name, properties, hadoopConf) or buildIcebergCatalog with a catalog-impl property naming a class that is missing from the runtime classpath, misspelled, not public, or lacking a public no-arg constructor.

Common situations: Typos in io.catalog-impl / catalog-impl config; the connector JAR (e.g. iceberg-aws, iceberg-nessie) not on the classpath of Spark/Flink/Trino; using a fully qualified class name from a different Iceberg major version that was renamed or moved; shading/relocation breaking reflection.

Related errors


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