apache/iceberg · error · java.lang.RuntimeException

Failed to instantiate DynamicRecordGeneratorSQL %s

Error message

Failed to instantiate DynamicRecordGeneratorSQL %s

What it means

IcebergTableSink.createDynamicRecordGenerator wraps any failure other than the interface-mismatch ClassCastException (e.g. ClassNotFoundException, missing (RowType) constructor, or constructor exceptions) into a RuntimeException naming the configured generator class. It means the configured DynamicTableRecordGenerator implementation could not be found or constructed reflectively.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/IcebergTableSink.java:298

  }

  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)
              .buildChecked();
      return ctor.newInstance(rowType);
    } 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);
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Add a public constructor taking exactly one RowType parameter: public MyGen(RowType rowType) { ... }.
  2. Ensure the jar containing the generator is on the Flink classpath (flink/lib or bundled in the user job jar) and the class name in the option is correct.
  3. Inspect the wrapped cause: ClassNotFoundException means classpath, NoSuchMethodException means constructor signature, other exceptions mean the constructor body threw.
  4. Recompile the generator against your exact iceberg-flink version; API changes can break the expected constructor or interface.
  5. Remove the custom generator option to use the default generator.

Example fix

// before
public MyGen() { } // no RowType constructor
// after
public MyGen(RowType rowType) {
  this.rowType = rowType;
}
// plus: flink run -C my-jar-with-generator.jar ...
Defensive patterns

Strategy: validation

Validate before calling

// Verify the class is loadable and has the required (RowType) constructor before configuring
Class<?> cls;
try {
  cls = Class.forName("com.example.MyGen", false,
      Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
  throw new IllegalStateException("Generator class not on classpath: com.example.MyGen", e);
}
try {
  cls.getConstructor(org.apache.flink.table.types.logical.RowType.class);
} catch (NoSuchMethodException e) {
  throw new IllegalStateException("Generator needs a public MyGen(RowType) constructor", e);
}

Try / catch

try {
  sink = ...; // sink creation that instantiates the generator
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Failed to instantiate DynamicRecordGeneratorSQL")) {
    Throwable cause = e.getCause();
    LOG.error("Generator init failed ({}): check classpath and RowType constructor",
        cause == null ? "unknown" : cause.getClass().getSimpleName(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Configuring the sink's dynamic record generator option to a class that is not on the classpath, has no public constructor accepting a single RowType argument, or throws from its constructor, when the Iceberg sink initializes the generator.

Common situations: Missing or misspelled class name in sink options; generator jar not distributed to all TaskManagers; constructor signature changed after an upgrade; generator constructor throwing due to bad config; shaded fat jar excluding the generator class.

Related errors


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