apache/flink · error · RuntimeException

SerializerFactory has not been initialized from configuratio

Error message

SerializerFactory has not been initialized from configuration.

What it means

RuntimeSerializerFactory.getSerializer throws this when its serializer field is null, meaning the factory was never initialized via readParametersFromConfig (or that read failed). It is a lifecycle-ordering bug in the caller: the factory only yields a serializer after being populated from a Configuration written on the job-submission side.

Source

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

            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);
        }
    }

    @Override
    public TypeSerializer<T> getSerializer() {
        if (this.serializer != null) {
            return this.serializer.duplicate();
        } else {
            throw new RuntimeException(
                    "SerializerFactory has not been initialized from configuration.");
        }
    }

    @Override
    public Class<T> getDataType() {
        return clazz;
    }

    // --------------------------------------------------------------------------------------------

    @Override
    public int hashCode() {
        return clazz.hashCode() ^ serializer.hashCode();
    }

    @Override
    public boolean equals(Object obj) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Follow the write->read->get lifecycle: construct with the serializer, writeParametersToConfig on the client; on the cluster construct no-arg and call readParametersFromConfig(config, userClassloader) before getSerializer().
  2. If readParametersFromConfig throws, abort and surface that exception; never fall through to getSerializer().
  3. In tests, always round-trip through a Configuration rather than using a bare factory.

Example fix

// before
RuntimeSerializerFactory<String> f = new RuntimeSerializerFactory<>();
TypeSerializer<String> s = f.getSerializer(); // NPE-guarded -> RuntimeException 685

// after
Configuration cfg = new Configuration();
new RuntimeSerializerFactory<>(String.class, new StringValueSerializer()).writeParametersToConfig(cfg);
RuntimeSerializerFactory<String> f2 = new RuntimeSerializerFactory<>();
f2.readParametersFromConfig(cfg, Thread.currentThread().getContextClassLoader());
TypeSerializer<String> s = f2.getSerializer();
Defensive patterns

Strategy: validation

Validate before calling

public static <T> TypeSerializer<T> initializedSerializer(
        RuntimeSerializerFactory<T> f, Configuration cfg, ClassLoader cl) throws Exception {
    f.readParametersFromConfig(cfg, cl);
    return f.getSerializer(); // getSerializer only after successful read
}

Prevention

When it happens

Trigger: new RuntimeSerializerFactory<>() (no-arg) followed directly by getSerializer(); or writeParametersToConfig failing on the sender so the receiver's readParametersFromConfig never ran; or readParametersFromConfig throwing (null config/cl -> NPE; deserialization failure) and getSerializer being called regardless.

Common situations: Utility code or tests reusing a factory instance across a failure boundary. Framework glue that constructs the factory reflectively but skips the read step. Calling getDataType()/getSerializer() on the sender-side instance after only using it as a template (sender instance actually keeps fields, but a no-arg constructed one does not).

Related errors


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