apache/flink · error · IllegalStateException

Unexpected serializer type.

Error message

Unexpected serializer type.

What it means

Thrown by MapStateDescriptor.getKeySerializer() when the state's serializer is not a MapSerializer. The method assumes the underlying serializer wraps a key serializer and a value serializer; if a custom or incompatible serializer was injected (e.g. via setStateSerializer or a config override), the cast to MapSerializer would be unsafe, so an explicit instanceof guard throws instead. This indicates the state descriptor's serializer was replaced after construction.

Solutions

  1. Ensure the MapStateDescriptor uses the default MapSerializer (do not override the serializer for map state).
  2. If restoring from a savepoint, verify the serializer snapshot is compatible with MapSerializer or re-register the correct serializer.
  3. If you need a custom serializer, access the raw serializer via getSerializer() instead of getKeySerializer().

Example fix

// before: custom serializer override breaks getKeySerializer
descriptor.initializeSerializerUnlessSet(() -> new CustomTypeSerializer<>());
descriptor.getKeySerializer(); // throws IllegalStateException

// after: let the descriptor build its own MapSerializer
descriptor.getKeySerializer(); // returns MapSerializer's key serializer
Defensive patterns

Strategy: type-guard

Validate before calling

TypeSerializer<?> ser = descriptor.getSerializer();
if (!(ser instanceof MapSerializer)) {
    throw new IllegalStateException(
        "Cannot get key serializer: underlying serializer is " + ser.getClass().getName());
}

Type guard

public static boolean hasMapSerializer(MapStateDescriptor<?, ?> desc) {
    return desc.getSerializer() instanceof MapSerializer;
}

Try / catch

try {
    return descriptor.getKeySerializer();
} catch (IllegalStateException e) {
    // fall back to raw serializer access
    return descriptor.getSerializer();
}

Prevention

When it happens

Trigger: Calling getKeySerializer() after the descriptor's serializer was overridden with a non-MapSerializer (e.g. a custom TypeSerializer injected via a StateBackend config or a restore from a savepoint with an incompatible serializer snapshot).

Common situations: Restoring a MapState from a savepoint whose serializer snapshot resolved to a non-map serializer; injecting a custom serializer via the state backend configuration; using a state backend that substitutes serializers internally.

Related errors


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

Appendix: source

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

     */
    public MapStateDescriptor(String name, Class<UK> keyClass, Class<UV> valueClass) {
        super(name, new MapTypeInfo<>(keyClass, valueClass), null);
    }

    @Override
    public Type getType() {
        return Type.MAP;
    }

    /**
     * Gets the serializer for the keys in the state.
     *
     * @return The serializer for the keys in the state.
     */
    public TypeSerializer<UK> getKeySerializer() {
        final TypeSerializer<Map<UK, UV>> rawSerializer = getSerializer();
        if (!(rawSerializer instanceof MapSerializer)) {
            throw new IllegalStateException("Unexpected serializer type.");
        }

        return ((MapSerializer<UK, UV>) rawSerializer).getKeySerializer();
    }

    /**
     * Gets the serializer for the values in the state.
     *
     * @return The serializer for the values in the state.
     */
    public TypeSerializer<UV> getValueSerializer() {
        final TypeSerializer<Map<UK, UV>> rawSerializer = getSerializer();
        if (!(rawSerializer instanceof MapSerializer)) {
            throw new IllegalStateException("Unexpected serializer type.");
        }

        return ((MapSerializer<UK, UV>) rawSerializer).getValueSerializer();
    }

View on GitHub (pinned to 2f3c205e92)