apache/flink · error · IllegalStateException
Serializer not yet initialized.
Error message
Serializer not yet initialized.
What it means
StateDescriptor v2 (package state.v2) getSerializer() returns serializer.duplicate() from the internal typeSerializer StateSerializerReference, which is empty until initializeSerializerUnlessSet(ExecutionConfig) runs. The v2 descriptor deliberately defers serializer creation so it can incorporate ExecutionConfig-driven serializer configuration. Invoking getSerializer before initialization throws.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/state/v2/StateDescriptor.java:135
}
@Nonnull
public StateTtlConfig getTtlConfig() {
return ttlConfig;
}
@Nonnull
public String getStateId() {
return stateId;
}
@Nonnull
public TypeSerializer<T> getSerializer() {
TypeSerializer<T> serializer = typeSerializer.get();
if (serializer != null) {
return serializer.duplicate();
} else {
throw new IllegalStateException("Serializer not yet initialized.");
}
}
@Internal
@Nullable
public TypeInformation<T> getTypeInformation() {
return typeSerializer.getTypeInformation();
}
// ------------------------------------------------------------------------
/**
* Checks whether the serializer has been initialized. Serializer initialization is lazy, to
* allow parametrization of serializers with an {@link ExecutionConfig} via {@link
* #initializeSerializerUnlessSet(ExecutionConfig)}.
*
* @return True if the serializers have been initialized, false otherwise.
*/View on GitHub (pinned to 2f3c205e92)
Solutions
- Call descriptor.initializeSerializerUnlessSet(executionConfig) before getSerializer(), using the ExecutionConfig from the v2 environment.
- Defer getSerializer to the operator open()/initialize phase where the runtime guarantees initialization.
- In tests, call initializeSerializerUnlessSet(new ExecutionConfig()) immediately after building the descriptor.
Example fix
// before
ValueStateDescriptor<Long> desc = new ValueStateDescriptor<>("v", Long.class);
TypeSerializer<Long> ser = desc.getSerializer(); // throws
// after
ValueStateDescriptor<Long> desc = new ValueStateDescriptor<>("v", Long.class);
desc.initializeSerializerUnlessSet(env.getConfig());
TypeSerializer<Long> ser = desc.getSerializer(); Defensive patterns
Strategy: validation
Validate before calling
if (!descriptor.isSerializerInitialized()) {
descriptor.initializeSerializerUnlessSet(
getRuntimeContext().getExecutionConfig());
}
TypeSerializer<T> ser = descriptor.getSerializer(); Type guard
static <T> TypeSerializer<T> safeGet(StateDescriptor<T> d, ExecutionConfig cfg) {
if (!d.isSerializerInitialized()) d.initializeSerializerUnlessSet(cfg);
return d.getSerializer();
} Try / catch
try {
return descriptor.getSerializer();
} catch (IllegalStateException e) {
descriptor.initializeSerializerUnlessSet(cfg);
return descriptor.getSerializer();
} Prevention
- Always initialize v2 descriptors before reading serializers.
- Keep serializer access inside open()/initialize hooks.
- Add tests that exercise the serializer after initialization.
When it happens
Trigger: Calling getSerializer() on a v2 StateDescriptor subclass (ValueStateDescriptor, ListStateDescriptor, etc. from flink-datastream-api) before the runtime initializes it; in user code or tests outside the normal open() lifecycle.
Common situations: DataStream v2 adoption where serializer access happens before state registration; custom v2 source/sink operators that touch the serializer during setup; unit tests constructing descriptors without running the initialization hook.
Related errors
- Serializer not yet initialized.
- Serializer not yet initialized.
- Could not create writer state serializer.
- Could not create committable serializer.
- Unexpected serializer type.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/ccb9a634521e092e.
Report an issue: GitHub.