apache/flink · error · IncompatibleKeysException
The number of specified keys is different.
Error message
The number of specified keys is different.
What it means
Thrown by Keys.areCompatible() as IncompatibleKeysException(SIZE_MISMATCH_MESSAGE) when two key specifications declare a different number of key fields. Flink requires join/coGroup/group keys on both sides to have matching arity so the runtime can pair key fields positionally; a size mismatch means the two sides cannot be key-aligned.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java:66
public abstract TypeInformation<?>[] getKeyFieldTypes();
public abstract TypeInformation<?>[] getOriginalKeyFieldTypes();
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;View on GitHub (pinned to 2f3c205e92)
Solutions
- Make the number of key fields identical on both sides of where(...) and equalTo(...).
- If the keys are semantically the same but split across fields, wrap one side in a KeySelector returning a composite key matching the other side's arity.
- Re-read the stack trace to confirm which pair of key specs disagree (left vs right).
Example fix
// before dsA.join(dsB).where(0, 1).equalTo(0); // after dsA.join(dsB).where(0, 1).equalTo(0, 1);
Defensive patterns
Strategy: validation
Validate before calling
int[] left = ...; int[] right = ...;
if (left.length != right.length) {
throw new IllegalArgumentException(
"Join key arity mismatch: " + left.length + " vs " + right.length);
} Try / catch
try {
a.join(b).where(leftKeys).equalTo(rightKeys);
} catch (Exception e) {
if (e.getCause() instanceof Keys.IncompatibleKeysException) { /* fix key arity */ }
throw e;
} Prevention
- Keep join/coGroup key arity equal on both sides; assert it in tests.
- When evolving a schema, update both sides of every join key declaration.
- Prefer KeySelectors returning a single typed key to avoid positional-arity bugs.
When it happens
Trigger: Calling datasetA.join(datasetB).where(0,1).equalTo(0) (2 key fields vs 1); mixing a tuple-position key with a KeySelector returning a single-field type in a join; using different key expressions on left and right of a coGroup.
Common situations: Joining two DataSets with mismatched key arity (e.g. .where(0,1).equalTo(0)); evolving one side's schema to add a key field without updating the other; copy-paste of join declarations with a different field count.
Related errors
- {typeInformation} and {typeInformation2} are not compatible
- The partitioner is incompatible with the key type. Partition
- Input type of coGroup must be one of composite types or atom
- The binary operation {} has no first input.
- The binary operation {} has no second input.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/12971c1fcff8c1e9.
Report an issue: GitHub.