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

  1. Ensure the KeySelector instance is constructed and non-null before passing it.
  2. Use Objects.requireNonNull(selector, "keySelector") at the call site for an earlier, clearer failure.
  3. 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

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


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