apache/flink · error · NullPointerException
Key extractor must not be null.
Error message
Key extractor must not be null.
What it means
Thrown by the SelectorFunctionKeys constructor when the KeySelector argument is null. A KeySelector defines how each record maps to its key; a null selector would NPE during partitioning, sorting, and joining, so it is rejected up front with a NullPointerException.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/Keys.java:96
// --------------------------------------------------------------------------------------------
// 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;
public SelectorFunctionKeys(
KeySelector<T, K> keyExtractor,
TypeInformation<T> inputType,
TypeInformation<K> keyType) {
if (keyExtractor == null) {
throw new NullPointerException("Key extractor must not be null.");
}
if (keyType == null) {
throw new NullPointerException("Key type must not be null.");
}
if (!keyType.isKeyType()) {
throw new InvalidProgramException(
"Return type "
+ keyType
+ " of KeySelector "
+ keyExtractor.getClass()
+ " is not a valid key type");
}
this.keyExtractor = keyExtractor;
this.inputType = inputType;
this.keyType = keyType;
this.originalKeyTypes = new TypeInformation[] {keyType};View on GitHub (pinned to 2f3c205e92)
Solutions
- Ensure the KeySelector instance is constructed and non-null before passing it.
- Use Objects.requireNonNull(selector, "keySelector") at the call site for an earlier, clearer failure.
- If the selector is conditional, supply a concrete selector (e.g. identity) rather than null.
Example fix
// before KeySelector<IN,KEY> sel = registry.get(name); ds.keyBy(sel); // after KeySelector<IN,KEY> sel = Objects.requireNonNull(registry.get(name), "selector for " + name); ds.keyBy(sel);
Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(keySelector, "keySelector"); new SelectorFunctionKeys<>(keySelector, inputType, keyType);
Prevention
- Always construct the KeySelector before passing it; never forward an uninitialised field.
- Use Objects.requireNonNull at the call site for a clearer error.
- Avoid optional-returning suppliers for selectors; provide a concrete default.
When it happens
Trigger: Calling a keyBy()/groupBy()/join API with a KeySelector variable that is null; passing a method reference that resolved to null due to a reflection/lambda capture bug; building keys programmatically from an optional that was empty.
Common situations: Passing an uninitialized KeySelector field; refactoring a lambda into a variable that was never assigned; framework code that obtains the selector from a registry returning null.
Related errors
- Key type must not be null.
- Return type {keyType} of KeySelector {keyExtractor.getClass(
- Expression key may not be null.
- The broadcast input name may not be null.
- The broadcast input root operator may not be null.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/c5297130185db28f.
Report an issue: GitHub.