apache/flink · error · IllegalArgumentException

EnumTypeInfo can only be used for subclasses of java.lang.En

Error message

EnumTypeInfo can only be used for subclasses of java.lang.Enum

What it means

Thrown by the EnumTypeInfo constructor when the supplied class is not a subclass of java.lang.Enum. EnumTypeInfo is a specialized, schema-free type information valid only for Java enums; passing any other class is a programming error caught by an Enum.class.isAssignableFrom check.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/EnumTypeInfo.java:51

/**
 * A {@link TypeInformation} for java enumeration types.
 *
 * @param <T> The type represented by this type information.
 */
@Public
public class EnumTypeInfo<T extends Enum<T>> extends TypeInformation<T> implements AtomicType<T> {

    private static final long serialVersionUID = 8936740290137178660L;

    private final Class<T> typeClass;

    @PublicEvolving
    public EnumTypeInfo(Class<T> typeClass) {
        checkNotNull(typeClass, "Enum type class must not be null.");

        if (!Enum.class.isAssignableFrom(typeClass)) {
            throw new IllegalArgumentException(
                    "EnumTypeInfo can only be used for subclasses of " + Enum.class.getName());
        }

        this.typeClass = typeClass;
    }

    @Override
    @PublicEvolving
    public TypeComparator<T> createComparator(
            boolean sortOrderAscending, ExecutionConfig executionConfig) {
        return new EnumComparator<T>(sortOrderAscending);
    }

    @Override
    @PublicEvolving
    public boolean isBasicType() {
        return false;
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Only construct EnumTypeInfo with a Class<? extends Enum>.
  2. Let TypeExtractor infer type information automatically rather than constructing EnumTypeInfo by hand.
  3. For non-enum classes use PojoTypeInfo / GenericTypeInfo / a custom TypeInformation instead.

Example fix

// before
new EnumTypeInfo<>(MyConstantsClass.class); // not an enum

// after (if it really is an enum)
public enum MyEnum { A, B; }
new EnumTypeInfo<>(MyEnum.class);
// or, for a non-enum class, let TypeExtractor handle it:
TypeInformation.of(MyConstantsClass.class);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!Enum.class.isAssignableFrom(typeClass)) {
    throw new IllegalArgumentException("EnumTypeInfo requires a java.lang.Enum subclass: " + typeClass);
}

Type guard

static boolean isEnumType(Class<?> c) {
    return c != null && Enum.class.isAssignableFrom(c);
}

Prevention

When it happens

Trigger: Explicitly constructing new EnumTypeInfo<>(SomeClass.class) where SomeClass is not an enum; a generic factory incorrectly routing a non-enum class to EnumTypeInfo.

Common situations: Hand-rolling TypeInformation for a class that merely looks enum-like (constants in a class); copy-paste of EnumTypeInfo construction for a non-enum type; misuse of the type system API.

Related errors


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