apache/flink · error · RuntimeException

Could not serialize serializer into the configuration.

Error message

Could not serialize serializer into the configuration.

What it means

RuntimeSerializerFactory.writeParametersToConfig Java-serializes both the type class and the TypeSerializer into the job Configuration. This error means that serialization failed, most commonly because the TypeSerializer instance (or the Class object's surrounding graph) is not java.io.Serializable. Flink's own serializers usually are; user-defined serializers frequently are not.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/runtime/RuntimeSerializerFactory.java:59

    // Because we read the class from the TaskConfig and instantiate ourselves
    public RuntimeSerializerFactory() {}

    public RuntimeSerializerFactory(TypeSerializer<T> serializer, Class<T> clazz) {
        if (serializer == null || clazz == null) {
            throw new NullPointerException();
        }

        this.clazz = clazz;
        this.serializer = serializer;
    }

    @Override
    public void writeParametersToConfig(Configuration config) {
        try {
            InstantiationUtil.writeObjectToConfig(clazz, config, CONFIG_KEY_CLASS);
            InstantiationUtil.writeObjectToConfig(serializer, config, CONFIG_KEY_SER);
        } catch (Exception e) {
            throw new RuntimeException("Could not serialize serializer into the configuration.", e);
        }
    }

    @Override
    public void readParametersFromConfig(Configuration config, ClassLoader cl)
            throws ClassNotFoundException {
        if (config == null || cl == null) {
            throw new NullPointerException();
        }

        try {
            this.clazz = InstantiationUtil.readObjectFromConfig(config, CONFIG_KEY_CLASS, cl);
            this.serializer = InstantiationUtil.readObjectFromConfig(config, CONFIG_KEY_SER, cl);
        } catch (ClassNotFoundException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("Could not load deserializer from the configuration.", e);
        }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Make the custom TypeSerializer implement java.io.Serializable and give it a stable serialVersionUID.
  2. Convert inner/anonymous serializer classes to static nested or top-level classes so they do not capture the enclosing (often non-serializable) instance.
  3. Find the offending field from the nested NotSerializableException and mark it transient, rebuilding it lazily after deserialization.
  4. Where possible, register a serializer factory pattern (like RuntimeSerializerFactory itself) or use Flink-provided TypeInformation/serializer instances, which are already serializable.

Example fix

// before
public class MySer extends TypeSerializer<MyPojo> { // not Serializable -> 683
    private final Codec codec = Codec.create();
}

// after
public class MySer extends TypeSerializer<MyPojo> implements Serializable {
    private static final long serialVersionUID = 1L;
    private transient Codec codec;
    private Codec codec() { if (codec == null) codec = Codec.create(); return codec; }
}
Defensive patterns

Strategy: validation

Validate before calling

public static void assertSerializerSerializable(TypeSerializer<?> ser) {
    if (!(ser instanceof java.io.Serializable)) {
        throw new IllegalStateException("Serializer " + ser.getClass().getName()
            + " is not Serializable; RuntimeSerializerFactory.writeParametersToConfig will fail");
    }
    org.apache.flink.util.InstantiationUtil.serializeObject(ser);
}

Try / catch

try {
    factory.writeParametersToConfig(config);
} catch (RuntimeException e) {
    Throwable c = e.getCause(); // NotSerializableException names the offending class
    throw new IllegalStateException("Serializer graph not serializable: " + c, e);
}

Prevention

When it happens

Trigger: Executing a job where a RuntimeSerializerFactory wraps a custom TypeSerializer that does not implement Serializable, or whose fields reference non-serializable objects. Also triggered if writeObject on the serializer throws (final fields, failing custom writeObject).

Common situations: Custom TypeSerializer registered via env.registerTypeWithSerializer or provided in a TypeInformation that keeps a non-serializable helper (schema registry client, pooled buffer, model object). Serializer implemented as a non-static inner class. Serializer capturing 'this' of the enclosing job class which itself holds an ExecutionEnvironment (a classic NotSerializableException).

Related errors


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