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
- Ensure the class referenced in the 'class' field extends TypeInfoFactory<?> and implements the createTypeInfo method.
- If you meant to register a custom serializer, use type 'kryo' or 'pojo' instead of 'typeinfo'.
- 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
- Verify the factory class extends TypeInfoFactory<?> before configuring it.
- Do not confuse TypeInfoFactory with TypeInformation or TypeSerializer.
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
- Serializing the source elements failed: {e.getMessage()}
- {e.getMessage()}
- Return type {keyType} of KeySelector {keyExtractor.getClass(
- The implementation of AbstractDeserializationSchema is using
- Unsupported serializer type %s for %s
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/c8f110807d0dffc2.
Report an issue: GitHub.