apache/flink · error · IllegalArgumentException

Type at position {} is not a basic type.

Error message

Type at position {} is not a basic type.

What it means

Thrown by TupleTypeInfo.getBasicTupleTypeInfo(Class<?>...) when BasicTypeInfo.getInfoFor(type) returns null — meaning the Class is not one of Flink's recognized basic types (String, Boolean, Byte, Short, Integer, Long, Float, Double, Character, Date, Void, BigInteger, BigDecimal, or SQL date/time types). This is a plain IllegalArgumentException.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/java/typeutils/TupleTypeInfo.java:223

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

    @PublicEvolving
    public static <X extends Tuple> TupleTypeInfo<X> getBasicTupleTypeInfo(Class<?>... basicTypes) {
        if (basicTypes == null || basicTypes.length == 0) {
            throw new IllegalArgumentException();
        }

        TypeInformation<?>[] infos = new TypeInformation<?>[basicTypes.length];
        for (int i = 0; i < infos.length; i++) {
            Class<?> type = basicTypes[i];
            if (type == null) {
                throw new IllegalArgumentException("Type at position " + i + " is null.");
            }

            TypeInformation<?> info = BasicTypeInfo.getInfoFor(type);
            if (info == null) {
                throw new IllegalArgumentException(
                        "Type at position " + i + " is not a basic type.");
            }
            infos[i] = info;
        }

        @SuppressWarnings("unchecked")
        TupleTypeInfo<X> tupleInfo = (TupleTypeInfo<X>) new TupleTypeInfo<Tuple>(infos);
        return tupleInfo;
    }

    @SuppressWarnings("unchecked")
    @PublicEvolving
    public static <X extends Tuple> TupleTypeInfo<X> getBasicAndBasicValueTupleTypeInfo(
            Class<?>... basicTypes) {
        if (basicTypes == null || basicTypes.length == 0) {
            throw new IllegalArgumentException();
        }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Use only basic types: String, Boolean, Byte, Short, Integer, Long, Float, Double, Character, Date, Void, BigInteger, BigDecimal.
  2. For non-basic types use 'new TupleTypeInfo<>(typeInfo1, typeInfo2, ...)' with explicit TypeInformation objects instead of the basic-only factory.
  3. For custom classes, use TypeInformation.of(MyClass.class) and pass it to the TupleTypeInfo constructor.

Example fix

// before
TupleTypeInfo.getBasicTupleTypeInfo(MyPojo.class, Integer.class);
// after
new TupleTypeInfo<>(TypeInformation.of(MyPojo.class), Types.INT);
Defensive patterns

Strategy: validation

Validate before calling

Set<Class<?>> BASIC = Set.of(
    String.class, Boolean.class, Byte.class, Short.class,
    Integer.class, Long.class, Float.class, Double.class,
    Character.class, Date.class, Void.class,
    BigInteger.class, BigDecimal.class);
for (Class<?> c : basicTypes) {
    if (!BASIC.contains(c)) {
        throw new IllegalArgumentException(
            "Not a basic type: " + c);
    }
}

Type guard

boolean isBasicType(Class<?> c) {
    return BasicTypeInfo.getInfoFor(c) != null;
}

Prevention

When it happens

Trigger: Calling TupleTypeInfo.getBasicTupleTypeInfo(MyCustomClass.class) or getBasicTupleTypeInfo(int[].class). BasicTypeInfo.getInfoFor only recognizes primitive wrappers and a handful of JDK types.

Common situations: Developer passes a custom POJO, enum, array, or collection class to a method that only accepts basic types. Common when migrating from a generic Tuple<Object,...> or when assuming Flink supports arbitrary classes in getBasicTupleTypeInfo.

Related errors


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