apache/iceberg · error · java.lang.RuntimeException

Failed to instantiate DynamicRecordGeneratorSQL %s

Error message

Failed to instantiate DynamicRecordGeneratorSQL %s

What it means

Generic wrapper RuntimeException raised when instantiating a configured DynamicRecordGeneratorSQL fails for any reason other than a ClassCastException — e.g. class not found, no matching constructor, or the constructor threw. The original cause is chained.

Source

Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/IcebergTableSink.java:296

  private DynamicTableRecordGenerator createDynamicRecordGenerator(String generatorImpl) {
    RowType rowType = (RowType) resolvedSchema.toSourceRowDataType().getLogicalType();

    DynConstructors.Ctor<DynamicTableRecordGenerator> ctor;

    try {
      ctor =
          DynConstructors.builder(DynamicTableRecordGenerator.class)
              .loader(IcebergTableSink.class.getClassLoader())
              .impl(generatorImpl, RowType.class)
              .impl(generatorImpl, RowType.class, Map.class, Configuration.class)
              .buildChecked();
      return ctor.newInstance(rowType, writeProps, fromReadableConfig());
    } catch (ClassCastException e) {
      throw new IllegalArgumentException(
          String.format("Class %s does not implement DynamicRecordGeneratorSQL", generatorImpl), e);
    } catch (Exception e) {
      throw new RuntimeException(
          String.format("Failed to instantiate DynamicRecordGeneratorSQL %s", generatorImpl), e);
    }
  }

  private Configuration fromReadableConfig() {
    return readableConfig instanceof Configuration
        ? (Configuration) readableConfig
        : Configuration.fromMap(readableConfig.toMap());
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Read the chained 'Caused by' to find the root failure (ClassNotFound, NoSuchMethod, or ctor exception).
  2. Ensure the generator class is on the Flink cluster classpath (shaded into the job jar or in Flink /lib).
  3. Implement one of the supported constructors: (RowType), (RowType, Map<String,String>), or (RowType, Map<String,String>, Configuration).

Example fix

// before
public MyGen(RowType rowType, SomeCustomCfg cfg) { ... } // no matching ctor
// after
public MyGen(RowType rowType, Map<String, String> writeProps, Configuration conf) { ... }
Defensive patterns

Strategy: validation

Validate before calling

Class<?> clz = Class.forName(generatorImpl, true, loader);
clz.getConstructor(RowType.class, Map.class, Configuration.class); // or other supported sig

Type guard

if (gen == null) throw new IllegalStateException("generator not instantiated: " + generatorImpl);

Try / catch

try { gen = ctor.newInstance(rowType, writeProps, conf); } catch (Exception e) { throw new RuntimeException("Cannot instantiate generator " + generatorImpl, e); }

Prevention

When it happens

Trigger: Configured generator class name missing from classpath; class has no constructor matching (RowType), (RowType, Map), or (RowType, Map, Configuration); the generator's constructor throws during newInstance.

Common situations: Job jar not shipping the generator class to TaskManagers; constructor reading missing config keys and throwing; upgrading Iceberg changed the supported constructor signatures.

Related errors


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