apache/beam · error · RuntimeException

Failed to initialize EMPTY DeleteFileIndex

Error message

Failed to initialize EMPTY DeleteFileIndex

What it means

createEmptyInstance builds an EMPTY DeleteFileIndex via a reflective constructor call on the Iceberg PartitionMap-backed index. Any failure of reflection (constructor signature change across Iceberg versions, class initialization error) is wrapped in this RuntimeException.

Solutions

  1. Align the Iceberg runtime version on the classpath with the version Beam's iceberg module was built against
  2. Inspect the wrapped cause (e) to identify the exact reflection failure (NoSuchMethodException vs IncompatibleClassChangeError)
  3. Upgrade or downgrade the org.apache.iceberg:iceberg-core dependency to a compatible version

Example fix

// before (pom.xml)
<dependency><groupId>org.apache.iceberg</groupId><artifactId>iceberg-core</artifactId><version>1.6.0</version></dependency>
// after
<dependency><groupId>org.apache.iceberg</groupId><artifactId>iceberg-core</artifactId><version>1.4.3</version></dependency> <!-- match Beam's tested version -->
Defensive patterns

Strategy: try-catch

Validate before calling

Class<?> idx = Class.forName("org.apache.iceberg.io.DeleteFileIndex");
// confirm constructor shape matches what Beam reflects on, at job-submission time

Try / catch

try {
  DeleteFileIndex idx = BeamBaseIncrementalChangelogScan.EMPTY;
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("Failed to initialize EMPTY DeleteFileIndex")) {
    LOG.error("Iceberg runtime version mismatch: {}", e.getCause(), e);
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling BeamBaseIncrementalChangelogScan.EMPTY (which calls createEmptyInstance) on an Iceberg runtime version whose DeleteFileIndex/PartitionMap constructor signature no longer matches the (PartitionMap.class, Map.class, Map.class...) shape invoked reflectively.

Common situations: Beam's iceberg module compiled against one Iceberg version but deployed with a different Iceberg on the classpath (version conflict); internal Iceberg API changed in a newer release.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/0b78977ab3f6d590. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/iceberg/src/main/java/org/apache/iceberg/BeamBaseIncrementalChangelogScan.java:79

public class BeamBaseIncrementalChangelogScan
    extends BaseIncrementalScan<
        IncrementalChangelogScan, ChangelogScanTask, ScanTaskGroup<ChangelogScanTask>>
    implements IncrementalChangelogScan {
  private static final DeleteFileIndex EMPTY = createEmptyInstance();

  private static DeleteFileIndex createEmptyInstance() {
    try {
      var constructor =
          DeleteFileIndex.class.getDeclaredConstructor(
              DeleteFileIndex.EqualityDeletes.class,
              PartitionMap.class,
              PartitionMap.class,
              Map.class,
              Map.class);
      constructor.setAccessible(true);
      return constructor.newInstance(null, null, null, null, null);
    } catch (Exception e) {
      throw new RuntimeException("Failed to initialize EMPTY DeleteFileIndex", e);
    }
  }

  private static final Logger LOG = LoggerFactory.getLogger(BeamBaseIncrementalChangelogScan.class);

  public BeamBaseIncrementalChangelogScan(Table table) {
    this(table, table.schema(), TableScanContext.empty());
  }

  private BeamBaseIncrementalChangelogScan(Table table, Schema schema, TableScanContext context) {
    super(table, schema, context);
  }

  @Override
  protected IncrementalChangelogScan newRefinedScan(
      Table newTable, Schema newSchema, TableScanContext newContext) {
    return new BeamBaseIncrementalChangelogScan(newTable, newSchema, newContext);
  }

View on GitHub (pinned to 12126d8942)