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
- Add a public constructor taking exactly one RowType parameter: public MyGen(RowType rowType) { ... }.
- 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.
- Inspect the wrapped cause: ClassNotFoundException means classpath, NoSuchMethodException means constructor signature, other exceptions mean the constructor body threw.
- Recompile the generator against your exact iceberg-flink version; API changes can break the expected constructor or interface.
- 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
- Ship the generator class in the user job jar so it reaches every TaskManager.
- Provide a public constructor accepting exactly one RowType argument.
- Keep constructor logic side-effect-free; validate config lazily to avoid instantiation throws.
- Log the wrapped cause when debugging: ClassNotFoundException = classpath, NoSuchMethodException = signature, other = constructor body threw.
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
- Class %s does not implement DynamicRecordGeneratorSQL
- Cannot initialize AdlsTokenCredentialProvider, missing no-ar
- Failed to instantiate DynamicRecordGeneratorSQL %s
- Class %s does not implement DynamicRecordGeneratorSQL
- Failed to instantiate DynamicRecordGeneratorSQL %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/f7f702e73e1b3a7f.
Report an issue: GitHub.