apache/flink · error · IllegalArgumentException

Class is not a TypeInfoFactory.

Error message

Class is not a TypeInfoFactory.

What it means

Thrown by TypeExtractor.registerFactory when the provided factory class does not implement TypeInfoFactory. The method checks TypeInfoFactory.class.isAssignableFrom(factory) and rejects any class that is not a subtype. This is a programming error: the caller passed a class that is not a valid TypeInfoFactory implementation.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractor.java:163

            registeredTypeInfoFactories = new HashMap<>();

    /**
     * Registers a type information factory globally for a certain type. Every following type
     * extraction operation will use the provided factory for this type. The factory will have the
     * highest precedence for this type. In a hierarchy of types the registered factory has higher
     * precedence than annotations at the same level but lower precedence than factories defined
     * down the hierarchy.
     *
     * @param t type for which a new factory is registered
     * @param factory type information factory that will produce {@link TypeInformation}
     */
    @Internal
    public static void registerFactory(Type 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);
    }

    // --------------------------------------------------------------------------------------------
    //  Function specific methods
    // --------------------------------------------------------------------------------------------

    @PublicEvolving
    public static <IN, OUT> TypeInformation<OUT> getMapReturnTypes(
            MapFunction<IN, OUT> mapInterface, TypeInformation<IN> inType) {
        return getMapReturnTypes(mapInterface, inType, null, false);
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Ensure the factory class extends TypeInfoFactory<T> and implements createTypeInfo(Type, Map).
  2. Check the class hierarchy: the registered class must be a direct or indirect subtype of TypeInfoFactory.
  3. Use the correct class reference in the registerFactory call.

Example fix

// before
TypeExtractor.registerFactory(MyType.class, MyTypeInfo.class); // MyTypeInfo extends TypeInformation, not TypeInfoFactory
// after
public class MyTypeInfoFactory extends TypeInfoFactory<MyType> {
    public TypeInformation<MyType> createTypeInfo(Type t, Map<String, TypeInformation<?>> m) {
        return new MyTypeInfo();
    }
}
TypeExtractor.registerFactory(MyType.class, MyTypeInfoFactory.class);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!TypeInfoFactory.class.isAssignableFrom(factory)) {
    throw new IllegalArgumentException(
        factory + " must extend TypeInfoFactory");
}
TypeExtractor.registerFactory(type, factory);

Type guard

static boolean isValidFactory(Class<?> factory) {
    return TypeInfoFactory.class.isAssignableFrom(factory);
}

Prevention

When it happens

Trigger: Calling TypeExtractor.registerFactory(type, SomeClass.class) where SomeClass does not extend TypeInfoFactory. Passing a raw Class without the generic bound. Accidentally passing a TypeInformation subclass instead of a TypeInfoFactory subclass.

Common situations: Developer confuses TypeInfoFactory (produces TypeInformation) with TypeInformation itself. Custom type factory implementation that forgot to extend TypeInfoFactory. Copy-paste error registering the wrong class.

Related errors


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