apache/flink · error · IncompatibleKeysException

{typeInformation} and {typeInformation2} are not compatible

Error message

{typeInformation} and {typeInformation2} are not compatible

What it means

Thrown by Keys.areCompatible() as IncompatibleKeysException(typeInformation, typeInformation2) when two key specifications have the same arity but at some position the key field types differ (e.g. BasicTypeInfo.STRING vs BasicTypeInfo.INT). The runtime pairs key fields positionally and requires exact type equality for comparator selection.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java:70

    public abstract <E> void validateCustomPartitioner(
            Partitioner<E> partitioner, TypeInformation<E> typeInfo);

    public boolean isEmpty() {
        return getNumberOfKeyFields() == 0;
    }

    /** Check if two sets of keys are compatible to each other (matching types, key counts) */
    public boolean areCompatible(Keys<?> other) throws IncompatibleKeysException {

        TypeInformation<?>[] thisKeyFieldTypes = this.getKeyFieldTypes();
        TypeInformation<?>[] otherKeyFieldTypes = other.getKeyFieldTypes();

        if (thisKeyFieldTypes.length != otherKeyFieldTypes.length) {
            throw new IncompatibleKeysException(IncompatibleKeysException.SIZE_MISMATCH_MESSAGE);
        } else {
            for (int i = 0; i < thisKeyFieldTypes.length; i++) {
                if (!thisKeyFieldTypes[i].equals(otherKeyFieldTypes[i])) {
                    throw new IncompatibleKeysException(
                            thisKeyFieldTypes[i], otherKeyFieldTypes[i]);
                }
            }
        }
        return true;
    }

    // --------------------------------------------------------------------------------------------
    //  Specializations for expression-based / extractor-based grouping
    // --------------------------------------------------------------------------------------------

    public static class SelectorFunctionKeys<T, K> extends Keys<T> {

        private final KeySelector<T, K> keyExtractor;
        private final TypeInformation<T> inputType;
        private final TypeInformation<K> keyType;
        private final List<FlatFieldDescriptor> keyFields;
        private final TypeInformation<?>[] originalKeyTypes;

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Align the key types exactly on both sides (e.g. cast or map one side so both keys are the same TypeInformation).
  2. If types are logically compatible, project one side through a map to the other's key type before joining.
  3. Inspect the two TypeInformation values named in the message to identify the divergent field position.

Example fix

// before (a.key is String, b.key is Long)
dsA.join(dsB).where(0).equalTo(0);
// after — project a.key to Long
dsA.map(t -> Tuple2.of(Long.parseLong(t.f0), t.f1)).returns(Types.TUPLE(Types.LONG, Types.STRING))
   .join(dsB).where(0).equalTo(0);
Defensive patterns

Strategy: validation

Validate before calling

TypeInformation<?>[] lt = leftKeys.getKeyFieldTypes();
TypeInformation<?>[] rt = rightKeys.getKeyFieldTypes();
for (int i = 0; i < lt.length; i++) {
    if (!lt[i].equals(rt[i])) {
        throw new IllegalStateException("Key type mismatch at position " + i + ": " + lt[i] + " vs " + rt[i]);
    }
}

Try / catch

try {
    a.join(b).where(0).equalTo(0);
} catch (Exception e) {
    if (e.getCause() instanceof Keys.IncompatibleKeysException) { /* project key types to match */ }
    throw e;
}

Prevention

When it happens

Trigger: Calling .where(0).equalTo(0) on two DataSets where field 0 is a String on one side and an Integer on the other; joining a Long key with an Integer key; mismatched POJO field types used as keys.

Common situations: Joining datasets whose key columns have compatible-but-not-equal types (Long vs Integer, String vs a custom type); schema drift where one side's key column type changed; using a KeySelector that returns a different primitive wrapper on each side.

Related errors


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