apache/iceberg · error · ValidationException

Class not found

Error message

Class %s not found : %s

What it means

ResolvingFileIO maps a location's scheme to a FileIO implementation class name via implFromLocation, then loads it reflectively with Class.forName. ValidationException is thrown when that class name cannot be found on the classpath, typically because the corresponding FileIO module (e.g. Hadoop) is not a dependency.

Solutions

  1. Add the shaded FileIO runtime jar for the location's scheme (iceberg-aws-bundle, iceberg-azure-bundle, iceberg-gcp-bundle, or iceberg-hadoop-mr) to the classpath.
  2. Verify the fully-qualified class name of any custom FileIO configured for the scheme is correct and present in the deployed artifact.
  3. Run the job with a fat/shaded jar that does not exclude io.* classes from relocation.
  4. Check that the scheme prefix in the location is spelled correctly so the expected implementation is resolved.

Example fix

// before
spark-submit --packages org.apache.iceberg:iceberg-spark-runtime-4.1_2.13:... \
  job.jar  // s3:// paths fail: no S3FileIO on classpath

// after
spark-submit --packages org.apache.iceberg:iceberg-spark-runtime-4.1_2.13:...,org.apache.iceberg:iceberg-aws-bundle:... \
  job.jar
Defensive patterns

Strategy: validation

Validate before calling

String cls = ioProps.getOrDefault(scheme(location) + ".impl", defaultFor(scheme(location)));
try {
  Class.forName(cls);
} catch (ClassNotFoundException e) {
  throw new IllegalStateException("FileIO class missing from classpath: " + cls +
      ". Add the matching iceberg-*-bundle jar.", e);
}

Try / catch

try {
  catalog.initialize("app", props);
} catch (ValidationException e) {
  if (e.getMessage().contains("not found")) {
    log.error("FileIO implementation missing: add iceberg-aws-bundle/iceberg-hadoop-mr to classpath");
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling ResolvingFileIO.ioClass(location) (directly or indirectly via usesHadoopFileIO) with a location whose mapped FileIO class is missing from the runtime classpath, e.g. an s3/hdfs/abfs location without the matching FileIO module loaded.

Common situations: Deploying a Spark/Flink job without the iceberg-aws or iceberg-hadoop-mr shaded jar; shading that excludes FileIO implementations; typos in custom FileIO class names in configuration; a location scheme (e.g. gcs) with no registered implementation.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/io/ResolvingFileIO.java:244

          Preconditions.checkState(
              fileIO instanceof DelegateFileIO,
              "FileIO does not implement DelegateFileIO: " + fileIO.getClass().getName());

          return (DelegateFileIO) fileIO;
        });
  }

  @VisibleForTesting
  String implFromLocation(String location) {
    return SCHEME_TO_FILE_IO.getOrDefault(scheme(location), FALLBACK_IMPL);
  }

  public Class<?> ioClass(String location) {
    String fileIOClassName = implFromLocation(location);
    try {
      return Class.forName(fileIOClassName);
    } catch (ClassNotFoundException e) {
      throw new ValidationException("Class %s not found : %s", fileIOClassName, e.getMessage());
    }
  }

  private static String scheme(String location) {
    int colonPos = location.indexOf(":");
    if (colonPos > 0) {
      return location.substring(0, colonPos);
    }

    return null;
  }

  @SuppressWarnings({"checkstyle:NoFinalizer", "Finalize", "deprecation"})
  @Override
  protected void finalize() throws Throwable {
    super.finalize();
    if (!isClosed.get()) {
      close();

View on GitHub (pinned to 86d9c8fc54)