apache/flink · error · IllegalArgumentException

Name, aggregator, or convergence criterion must not be null

Error message

Name, aggregator, or convergence criterion must not be null

What it means

Thrown by AggregatorRegistry.registerAggregationConvergenceCriterion when name, aggregator, or convergenceCheck is null. Delta iterations require a named aggregator plus a ConvergenceCriterion that decides when iteration stops; all three are mandatory. A null convergence criterion would leave the iteration with no termination logic, and a null name/aggregator would break aggregation.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/aggregators/AggregatorRegistry.java:66

        this.registry.put(name, aggregator);
    }

    public Collection<AggregatorWithName<?>> getAllRegisteredAggregators() {
        ArrayList<AggregatorWithName<?>> list =
                new ArrayList<AggregatorWithName<?>>(this.registry.size());

        for (Map.Entry<String, Aggregator<?>> entry : this.registry.entrySet()) {
            @SuppressWarnings("unchecked")
            Aggregator<Value> valAgg = (Aggregator<Value>) entry.getValue();
            list.add(new AggregatorWithName<>(entry.getKey(), valAgg));
        }
        return list;
    }

    public <T extends Value> void registerAggregationConvergenceCriterion(
            String name, Aggregator<T> aggregator, ConvergenceCriterion<T> convergenceCheck) {
        if (name == null || aggregator == null || convergenceCheck == null) {
            throw new IllegalArgumentException(
                    "Name, aggregator, or convergence criterion must not be null");
        }

        Aggregator<?> genAgg = aggregator;

        Aggregator<?> previous = this.registry.get(name);
        if (previous != null && previous != genAgg) {
            throw new RuntimeException("An aggregator is already registered under the given name.");
        }

        this.registry.put(name, genAgg);
        this.convergenceCriterion = convergenceCheck;
        this.convergenceCriterionAggregatorName = name;
    }

    public String getConvergenceCriterionAggregatorName() {
        return this.convergenceCriterionAggregatorName;
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Validate all three arguments non-null before calling; build the criterion from a validated factory.
  2. If loading classes from config, instantiate and null-check each before registration.

Example fix

// before
registry.registerAggregationConvergenceCriterion(name, agg, null);
// after
Objects.requireNonNull(name, "name");
Objects.requireNonNull(aggregator, "aggregator");
Objects.requireNonNull(convergenceCheck, "convergence criterion");
registry.registerAggregationConvergenceCriterion(name, aggregator, convergenceCheck);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(name, "name");
Objects.requireNonNull(aggregator, "aggregator");
Objects.requireNonNull(convergenceCheck, "criterion");
registry.registerAggregationConvergenceCriterion(name, aggregator, convergenceCheck);

Prevention

When it happens

Trigger: Calling registerAggregationConvergenceCriterion(null, agg, criterion) or omitting the criterion (null); building the criterion from config that returned null.

Common situations: Custom delta-iteration jobs; tests wiring convergence by hand; aggregator class or criterion class loaded dynamically that failed to instantiate.

Related errors


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