apache/flink · error · RuntimeException
Could not instantiate record
Error message
Could not instantiate record
What it means
Thrown when JavaRecordBuilderFactory.build() cannot invoke a Java record's canonical constructor via Constructor.newInstance(). The RuntimeException wraps the reflective cause, which can be illegal access (non-public record), wrong argument count/types (schema evolution remapping mismatch), or an exception thrown by the record's compact constructor itself.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/JavaRecordBuilderFactory.java:91
/** Builder class for incremental record construction. */
@Internal
final class JavaRecordBuilder {
private final Object[] args;
JavaRecordBuilder() {
if (defaultConstructorArgs == null) {
args = new Object[canonicalConstructor.getParameterCount()];
} else {
args = Arrays.copyOf(defaultConstructorArgs, defaultConstructorArgs.length);
}
}
T build() {
try {
return canonicalConstructor.newInstance(args);
} catch (Exception e) {
throw new RuntimeException("Could not instantiate record", e);
}
}
/**
* Set record field by index. If parameter index mapping is provided, the index is mapped,
* otherwise it is used as is.
*
* @param i index of field to be set
* @param value field value
*/
void setField(int i, Object value) {
if (paramIndexMapping != null) {
args[paramIndexMapping[i]] = value;
} else {
args[i] = value;
}
}
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Inspect the wrapped cause in the stack trace (e.getCause()) - it names the real failure: access, argument mismatch, or constructor exception
- Make the record class public (top-level or a public nested type) so the canonical constructor is invocable
- If restoring old state, verify the record's component names/types match what the serializer snapshot expects, or realign fields so argIndexMapping is correct
- Fix the record's compact constructor if it rejects valid default values for newly added components
Example fix
// before: package-private record
record Event(String id, long ts) {}
// after: public record
public record Event(String id, long ts) {} Defensive patterns
Strategy: validation
Validate before calling
if (!Modifier.isPublic(recordClass.getModifiers())) {
throw new IllegalArgumentException("Record class must be public: " + recordClass);
}
if (!recordClass.isRecord()) {
throw new IllegalArgumentException("Not a record: " + recordClass);
} Type guard
static boolean isInstantiableRecord(Class<?> c) {
if (!c.isRecord() || !Modifier.isPublic(c.getModifiers())) {
return false;
}
try {
c.getDeclaredConstructor().setAccessible(true);
return true;
} catch (ReflectiveOperationException | RuntimeException e) {
return false;
}
} Try / catch
try {
T value = builder.build();
} catch (RuntimeException e) {
Throwable cause = e.getCause(); // IllegalAccessException | InvocationTargetException | IllegalArgumentException
throw new IllegalStateException("Record instantiation failed: " + cause, cause);
} Prevention
- Keep record classes public and their component types stable across job upgrades
- Unit-test serializer round-trips for every record type used in state
- Avoid compact-constructor validation that rejects restored default values
When it happens
Trigger: Deserializing or copying a Java record through Kryo/POJO serialization paths (e.g. KryoSerializer or PojoSerializer reading a record): canonicalConstructor.newInstance(args) throws IllegalAccessException, IllegalArgumentException, or InvocationTargetException; also when argIndexMapping from schema migration feeds mis-typed values.
Common situations: Record class is package-private or nested without being accessible to the user-code classloader; record read from a savepoint/checkpoint written with a different record layout (added/removed/reordered components); record compact constructor validates and throws on restored default values; user-code classloader isolation between the serializer and the record class.
Related errors
- Could not find record canonical constructor
- Failed to serialize value '{value}'
- Cannot register null class or serializer.
- Could not copy object by serializing/deserializing it.
- NoFetchingInput cannot prefetch data.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/af8131e0bd914225.
Report an issue: GitHub.