apache/flink · error · RuntimeException
Cannot initialize fields.
Error message
Cannot initialize fields.
What it means
PojoSerializer.initializeFields() iterates every POJO field and sets it to a default instance produced by the field's own TypeSerializer.createInstance(). This RuntimeException is thrown when Field.set() raises an IllegalAccessException — meaning the JVM refused the reflective write even though the field was previously made accessible. It indicates an access-control or encapsulation barrier, not a missing constructor.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/PojoSerializer.java:247
private T instantiateRaw() {
try {
if (constructor == null) {
constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
}
return constructor.newInstance();
} catch (Exception e) {
throw new RuntimeException("Cannot instantiate class.", e);
}
}
protected void initializeFields(T t) {
for (int i = 0; i < numFields; i++) {
if (fields[i] != null) {
try {
fields[i].set(t, fieldSerializers[i].createInstance());
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot initialize fields.", e);
}
}
}
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public T copy(T from) {
if (from == null) {
return null;
}
Class<?> actualType = from.getClass();
if (isRecord()) {
try {
JavaRecordBuilderFactory<T>.JavaRecordBuilder builder = recordFactory.newBuilder();
for (int i = 0; i < numFields; i++) {
if (fields[i] != null) {View on GitHub (pinned to 2f3c205e92)
Solutions
- If using Java modules, add 'opens your.package to org.apache.flink.core' in module-info.java (or launch with --add-opens).
- Remove the 'final' modifier from POJO fields that the serializer must write, or ensure the serializer does not need to initialize them (they are already non-null after construction).
- Provide a TypeSerializerSnapshot / custom serializer so Flink does not rely on reflective field writes.
- Verify that no SecurityManager or custom classloader is blocking reflective access.
- As a last resort, annotate the type for Kryo serialization to bypass POjoSerializer entirely.
Example fix
// before — final field in a sealed module; Field.set throws IllegalAccessException
public class Sensor {
public final String id; // final + not open → reflective write denied
public Sensor() { this.id = ""; }
}
// after — remove final so the serializer can write the field at restore time
public class Sensor {
public String id;
public Sensor() { this.id = ""; }
} Defensive patterns
Strategy: validation
Validate before calling
// Check that all non-static fields of the POJO are reflectively writable
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public static List<String> nonWritableFields(Class<?> clazz) {
List<String> bad = new ArrayList<>();
for (Field f : clazz.getDeclaredFields()) {
int mod = f.getModifiers();
if (Modifier.isStatic(mod)) continue;
try {
f.setAccessible(true);
// final fields may still reject set() on some JVMs
if (Modifier.isFinal(mod)) bad.add(f.getName() + " (final)");
} catch (SecurityException e) {
bad.add(f.getName() + " (inaccessible)");
}
}
return bad;
} Try / catch
// initializeFields is called internally; guard at the type-registration level
List<String> bad = nonWritableFields(MyPojo.class);
if (!bad.isEmpty()) {
throw new IllegalStateException(
"Fields not writable by PojoSerializer: " + bad
+ " — remove 'final' or open the module");
} Prevention
- Avoid final instance fields in POJO types meant for PojoSerializer (or initialize them in the no-arg constructor so the serializer does not need to overwrite them).
- Open the POJO package to Flink in module-info.java or via --add-opens.
- Ensure no SecurityManager blocks reflective field modification.
- Test PojoSerializer.createInstance() in CI for all domain types.
When it happens
Trigger: After the POJO is successfully constructed via instantiateRaw(), initializeFields() calls fields[i].set(t, fieldSerializers[i].createInstance()). If the reflective set is denied, IllegalAccessException is caught and re-thrown with this message.
Common situations: The field is final and the JVM version enforces reflective-write restrictions on final fields; the POJO class is in a named module whose package is not 'open' to Flink, so setAccessible(true) silently fails or Field.set is rejected at call time; a security manager denies reflective field modification. This is rarer than errors 660/661 because fields are made accessible during serializer setup, but module-system tightening (Java 16+ strong encapsulation by default) makes it increasingly common.
Related errors
- Cannot instantiate class.
- Cannot register null type class.
- Field '{}' could not be accessed.
- Could not instantiate record
- Could not find record canonical constructor
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/cdfad9216bdc7994.
Report an issue: GitHub.