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
- Align the key types exactly on both sides (e.g. cast or map one side so both keys are the same TypeInformation).
- If types are logically compatible, project one side through a map to the other's key type before joining.
- 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
- Make both join key columns the same TypeInformation (e.g. both Types.LONG).
- Project one side through a map when types are only logically compatible.
- Add a unit test asserting key type equality before executing the join.
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
- The number of specified keys is different.
- The partitioner is incompatible with the key type. Partition
- The binary operation {} has no first input.
- The binary operation {} has no second input.
- The filter factor cannot be smaller than zero.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/309d890f9533cba7.
Report an issue: GitHub.