apache/flink · error · IllegalArgumentException

Class is not a TypeInfoFactory.

Error message

Class is not a TypeInfoFactory.

What it means

Thrown by registerTypeWithTypeInfoFactory when the loaded factory class does not implement/extend TypeInfoFactory. The method first checks Preconditions.checkNotNull (for null) then verifies assignability. This guards the registeredTypeInfoFactories map against entries that would later fail during type extraction. The check uses TypeInfoFactory.class.isAssignableFrom(factory).

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/serialization/SerializerConfigImpl.java:475

    private void parseAndRegisterTypeFactory(
            ClassLoader classLoader, Class<?> t, Map<String, String> m) {
        Class<? extends TypeInfoFactory<?>> factoryClass =
                loadClass(m.get("class"), classLoader, "Could not load TypeInfoFactory's class");
        // Register in the global static factory map of TypeExtractor for now so that it can be
        // accessed from the static methods of TypeExtractor where SerializerConfig is currently
        // not accessible
        TypeExtractor.registerFactory(t, factoryClass);
        // Register inside SerializerConfig only for testing purpose for now
        registerTypeWithTypeInfoFactory(t, factoryClass);
    }

    private void registerTypeWithTypeInfoFactory(
            Class<?> t, Class<? extends TypeInfoFactory<?>> factory) {
        Preconditions.checkNotNull(t, "Type parameter must not be null.");
        Preconditions.checkNotNull(factory, "Factory parameter must not be null.");

        if (!TypeInfoFactory.class.isAssignableFrom(factory)) {
            throw new IllegalArgumentException("Class is not a TypeInfoFactory.");
        }
        if (registeredTypeInfoFactories.containsKey(t)) {
            throw new InvalidTypesException(
                    "A TypeInfoFactory for type '" + t + "' is already registered.");
        }
        registeredTypeInfoFactories.put(t, factory);
    }

    @Override
    public SerializerConfigImpl copy() {
        final SerializerConfigImpl newSerializerConfig = new SerializerConfigImpl();
        newSerializerConfig.configure(configuration, this.getClass().getClassLoader());

        getRegisteredTypesWithKryoSerializers()
                .forEach(
                        (c, s) ->
                                newSerializerConfig.registerTypeWithKryoSerializer(
                                        c, s.getSerializer()));

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Ensure the class referenced in the 'class' field extends TypeInfoFactory<?> and implements the createTypeInfo method.
  2. If you meant to register a custom serializer, use type 'kryo' or 'pojo' instead of 'typeinfo'.
  3. Verify with a unit test: TypeInfoFactory.class.isAssignableFrom(MyFactory.class).

Example fix

# before (wrong class)
pipeline.serialization-config: "class:com.example.MyType{type:typeinfo,class:com.example.MyTypeInformation}"

// Implement a TypeInfoFactory
public class MyTypeInfoFactory extends TypeInfoFactory<MyType> {
    @Override
    public TypeInformation<MyType> createTypeInfo(Type t, Map<String, TypeInformation<?>> context) {
        return new MyTypeInfo();
    }
}

# after
pipeline.serialization-config: "class:com.example.MyType{type:typeinfo,class:com.example.MyTypeInfoFactory}"
Defensive patterns

Strategy: validation

Validate before calling

Class<?> factoryClass = Class.forName(factoryName);
if (!TypeInfoFactory.class.isAssignableFrom(factoryClass)) {
    throw new IllegalArgumentException(
        factoryName + " does not extend TypeInfoFactory");
}

Type guard

public static boolean isTypeInfoFactory(Class<?> clazz) {
    return clazz != null && TypeInfoFactory.class.isAssignableFrom(clazz);
}

Prevention

When it happens

Trigger: Setting a typeinfo-type serialization-config entry whose 'class' points to a class that is not a TypeInfoFactory subclass. For example, pointing it at a regular TypeInformation class or a TypeSerializer by mistake.

Common situations: Confusing TypeInfoFactory with TypeInformation or TypeSerializer; pointing the factory class at a utility class; copy-paste of the wrong class name from documentation.

Related errors


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