apache/iceberg · error · UnsupportedOperationException

Failed to load Configuration after loading Configurable

Error message

Failed to load Configuration after loading Configurable

What it means

CatalogUtil.configureHadoopConf loads the Hadoop Configuration class reflectively after successfully loading a Configurable (a Catalog or FileIO). If Configuration itself cannot be loaded via the same classloader, this UnsupportedOperationException is thrown. The code comments note this 'shouldn't happen' because a Configurable cannot be loaded without first loading Configuration, so it indicates a corrupted or inconsistent classloader state.

Source

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

      return;
    }

    if (!configurableInterface.isInstance(maybeConfigurable)) {
      // not Configurable because the object does not implement the Configurable interface
      return;
    }

    Class<?> configurationClass;
    try {
      configurationClass =
          DynClasses.builder()
              .loader(maybeConfigurableLoader)
              .impl("org.apache.hadoop.conf.Configuration")
              .buildChecked();
    } catch (ClassNotFoundException e) {
      // this shouldn't happen because Configurable cannot be loaded without first loading
      // Configuration
      throw new UnsupportedOperationException(
          "Failed to load Configuration after loading Configurable", e);
    }

    ValidationException.check(
        configurationClass.isInstance(conf),
        "%s is not an instance of Configuration from the classloader for %s",
        conf,
        maybeConfigurable);

    DynMethods.BoundMethod setConf;
    try {
      setConf =
          DynMethods.builder("setConf")
              .impl(configurableInterface, configurationClass)
              .buildChecked()
              .bind(maybeConfigurable);
    } catch (NoSuchMethodException e) {
      // this shouldn't happen because Configurable was loaded and defines setConf

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify Hadoop's configuration classes are on the classpath of the same classloader that loads the catalog/FileIO implementation.
  2. Inspect any custom classloader passed via ClassLoader and ensure it delegates to the parent for org.apache.hadoop.* classes.
  3. Check for shading/relocation of org.apache.hadoop.conf.Configuration in a fat jar and un-relocate it or add the real hadoop-common dependency.
  4. Align Hadoop versions so the Configuration class is loadable by CatalogUtil's configured loader (catalog.loader.impl / catalog.classloader properties).

Example fix

// before (broken: custom classloader filters hadoop classes)
CatalogUtil.loadCatalog("org.apache.iceberg.hive.HiveCatalog", "hive", null, myIsolatingClassLoader);

// after (fix classloader delegation or use default loader)
CatalogUtil.loadCatalog("org.apache.iceberg.hive.HiveCatalog", "hive", null,
    Thread.currentThread().getContextClassLoader());
Defensive patterns

Strategy: try-catch

Validate before calling

ClassLoader cl = pluginClassLoader;
Class<?> conf = Class.forName("org.apache.hadoop.conf.Configuration", true, cl);
if (conf == null) { throw new IllegalStateException("Hadoop Configuration not loadable by plugin classloader"); }

Type guard

boolean hasHadoopConf(ClassLoader cl) {
  try { Class.forName("org.apache.hadoop.conf.Configuration", false, cl); return true; }
  catch (ClassNotFoundException e) { return false; }
}

Try / catch

try {
  CatalogUtil.loadCatalog(impl, name, properties, conf);
} catch (UnsupportedOperationException e) {
  if (e.getCause() instanceof ClassNotFoundException) {
    // fall back to default classloader or fail fast with a clear setup error
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling CatalogUtil.loadCatalog(...) or loadFileIO(...) with a custom classloader where the Configurable class loads but org.apache.hadoop.conf.Configuration does not resolve via DynClasses; or a classloader whose parent delegation is broken/filtered (shaded environments, exotic plugin classloaders).

Common situations: Hadoop jars are shaded/relocated or absent from the runtime classpath but a stub Configurable class is present; custom plugin classloaders that hide org.apache.hadoop packages; mismatched classloader hierarchies in Flink/Spark/Hive metastore plugin setups.

Related errors


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