apache/iceberg · error · RuntimeException
Failed to instantiate DynamicRecordGeneratorSQL %s
Error message
Failed to instantiate DynamicRecordGeneratorSQL %s
What it means
createDynamicRecordGenerator wraps any instantiation failure (constructor lookup error, invocation failure, wrong constructor signature) in a RuntimeException naming the generator class. It means reflection could not construct an instance of the configured DynamicRecordGeneratorSQL implementation for the given RowType, write properties, and configuration.
Source
Thrown at flink/v2.2/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
- Ensure the generator exposes a public constructor accepting (RowType, Map<String,String>, Configuration) or (RowType, Map<String,String>).
- Make the class public with a public constructor; check the cause stack trace for the underlying error.
- Rebuild the generator against the exact Iceberg Flink version in use.
Example fix
// before
class MyGen implements DynamicRecordGeneratorSQL { MyGen(RowType t) {...} } // no matching ctor
// after
public class MyGen implements DynamicRecordGeneratorSQL {
public MyGen(RowType rowType, Map<String, String> props, Configuration conf) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = Class.forName(generatorImpl);
boolean hasCtor = Arrays.stream(c.getConstructors()).anyMatch(k ->
k.getParameterCount() == 3 && k.getParameterTypes()[0] == RowType.class);
if (!hasCtor) throw new IllegalStateException("Generator lacks (RowType, Map, Configuration) ctor"); Try / catch
try { sink.write(...); } catch (RuntimeException e) { LOG.error("generator instantiation failed", e.getCause()); } Prevention
- Provide a public constructor matching (RowType, Map<String,String>, Configuration)
- Make generator classes and constructors public
- Test generator instantiation in a unit test before deploying
When it happens
Trigger: Configured generator class has no constructor matching (RowType), (RowType, Map), or (RowType, Map, Configuration); constructor throws; class lacks a public no-arg-accessible ctor; Class.forName fails during the Dissatisfied loader build.
Common situations: Custom generator built against a different Iceberg version so constructor signatures changed; class not public; constructor throwing on bad write properties.
Related errors
- Failed to instantiate DynamicRecordGeneratorSQL %s
- Failed to instantiate DynamicRecordGeneratorSQL %s
- Failed to instantiate DynamicRecordGeneratorSQL %s
- org.apache.iceberg.arrow.vectorized.ArrowVectorAccessors can
- Cannot initialize AdlsTokenCredentialProvider, missing no-ar
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/05d663e1989aec61.
Report an issue: GitHub.