apache/flink · error · IllegalStateException

Serializer not yet initialized.

Error message

Serializer not yet initialized.

What it means

MapStateDescriptor v2 getUserKeySerializer() returns serializer.duplicate() from the userKeySerializer StateSerializerReference, but the reference is still empty because the descriptor's serializers have not been initialized. The v2 descriptors (package state.v2) initialize lazily via initializeSerializerUnlessSet(ExecutionConfig), mirroring the v1 contract. Calling getUserKeySerializer before initialization violates that contract.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/state/v2/MapStateDescriptor.java:96

     * consider using the {@link #MapStateDescriptor(String, TypeInformation, TypeInformation)}
     * constructor.
     *
     * @param name The name of the {@code MapStateDescriptor}.
     * @param keyClass The class of the type of keys in the state.
     * @param valueClass The class of the type of values in the state.
     */
    public MapStateDescriptor(String name, Class<UK> keyClass, Class<UV> valueClass) {
        super(name, valueClass);
        this.userKeySerializer = new StateSerializerReference<>(keyClass);
    }

    @Nonnull
    public TypeSerializer<UK> getUserKeySerializer() {
        TypeSerializer<UK> serializer = userKeySerializer.get();
        if (serializer != null) {
            return serializer.duplicate();
        } else {
            throw new IllegalStateException("Serializer not yet initialized.");
        }
    }

    @Internal
    @Nullable
    public TypeInformation<UK> getUserKeyTypeInformation() {
        return userKeySerializer.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.
     */
    @Override
    public boolean isSerializerInitialized() {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Call mapStateDescriptor.initializeSerializerUnlessSet(executionConfig) with the ExecutionConfig (from the v2 environment or RuntimeContext) before getUserKeySerializer().
  2. Read the key serializer inside the operator's open()/initialize lifecycle hook, not at descriptor construction.
  3. In tests, call initializeSerializerUnlessSet(new ExecutionConfig()) right after constructing the descriptor.

Example fix

// before
MapStateDescriptor<String,Integer> desc =
    new MapStateDescriptor<>("m", String.class, Integer.class);
TypeSerializer<String> ks = desc.getUserKeySerializer(); // throws

// after
MapStateDescriptor<String,Integer> desc =
    new MapStateDescriptor<>("m", String.class, Integer.class);
desc.initializeSerializerUnlessSet(env.getConfig());
TypeSerializer<String> ks = desc.getUserKeySerializer();
Defensive patterns

Strategy: validation

Validate before calling

if (!mapStateDescriptor.isSerializerInitialized()) {
    mapStateDescriptor.initializeSerializerUnlessSet(
        getRuntimeContext().getExecutionConfig());
}
TypeSerializer<UK> ks = mapStateDescriptor.getUserKeySerializer();

Type guard

// Guard getUserKeySerializer with the v2 initialization check
if (!desc.isSerializerInitialized()) {
    desc.initializeSerializerUnlessSet(executionConfig);
}

Try / catch

try {
    return desc.getUserKeySerializer();
} catch (IllegalStateException e) {
    desc.initializeSerializerUnlessSet(cfg);
    return desc.getUserKeySerializer();
}

Prevention

When it happens

Trigger: Using the DataStream v2 API (flink-datastream-api) and calling getUserKeySerializer() on a MapStateDescriptor before the runtime has called initializeSerializerUnlessSet; in tests that construct a v2 descriptor and immediately pull the key serializer.

Common situations: Early adoption of DataStream v2 where documentation or examples pull serializers eagerly; custom v2 operators that need the key serializer before open(); test scaffolding that skips the initialization step.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/37fa4b50cc1f81ce. Report an issue: GitHub.