apache/flink · error · IllegalArgumentException
The number of iterations must be at least one.
Error message
The number of iterations must be at least one.
What it means
Thrown by BulkIterationBase.setMaximumNumberOfIterations(int num) when num is less than 1. A bulk iteration must run at least one iteration; zero or negative iteration counts are nonsensical and indicate a configuration error.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/operators/base/BulkIterationBase.java:149
new TerminationCriterionMapper<X>(),
new UnaryOperatorInformation<X, X>(type, type),
"Termination Criterion Aggregation Wrapper");
mapper.setInput(criterion);
this.terminationCriterion = mapper;
this.getAggregators()
.registerAggregationConvergenceCriterion(
TERMINATION_CRITERION_AGGREGATOR_NAME,
new TerminationCriterionAggregator(),
new TerminationCriterionAggregationConvergence());
}
/**
* @param num
*/
public void setMaximumNumberOfIterations(int num) {
if (num < 1) {
throw new IllegalArgumentException("The number of iterations must be at least one.");
}
this.numberOfIterations = num;
}
public int getMaximumNumberOfIterations() {
return this.numberOfIterations;
}
@Override
public AggregatorRegistry getAggregators() {
return this.aggregators;
}
/**
* @throws InvalidProgramException
*/
public void validate() throws InvalidProgramException {
if (this.input == null) {View on GitHub (pinned to 2f3c205e92)
Solutions
- Validate the iteration count is >= 1 before calling setMaximumNumberOfIterations; clamp or fail early.
- Use Math.max(1, num) to guarantee a minimum of one iteration when the value comes from external config.
- If the iteration count is genuinely zero (no work to do), skip creating the iteration entirely.
- Alternatively, use a termination criterion (setTerminationCriterion) instead of a fixed count when the number of iterations is uncertain.
Example fix
// before int maxIters = getConfiguredIterations(); // could be 0 iteration.setMaximumNumberOfIterations(maxIters); // throws if < 1 // after int maxIters = Math.max(1, getConfiguredIterations()); iteration.setMaximumNumberOfIterations(maxIters);
Defensive patterns
Strategy: validation
Validate before calling
void safeSetMaxIterations(BulkIterationBase<?> iter, int num) {
if (num < 1) {
throw new IllegalArgumentException("Iteration count must be >= 1, got: " + num);
}
iter.setMaximumNumberOfIterations(num);
} Type guard
boolean isValidIterationCount(int num) {
return num >= 1;
} Try / catch
try {
iteration.setMaximumNumberOfIterations(computedCount);
} catch (IllegalArgumentException e) {
// count was < 1; clamp or fail
iteration.setMaximumNumberOfIterations(Math.max(1, computedCount));
} Prevention
- Validate iteration counts come from configuration with a minimum of 1.
- Use Math.max(1, value) when the count is dynamically computed.
- If the count is zero, skip creating the iteration entirely.
When it happens
Trigger: Calling iteration.setMaximumNumberOfIterations(0) or with a negative value. Passing a computed iteration count that could be zero or negative due to upstream logic.
Common situations: Dynamically computing the number of iterations from data or config (e.g., Math.max(0, someValue)) without clamping to at least 1. Passing a user-provided configuration value that was not validated. Integer underflow or off-by-one in iteration count calculation.
Related errors
- Operator for initial partial solution is not set.
- Operator producing the next version of the partial solution
- No termination condition is set (neither fix number of itera
- The filter factor cannot be smaller than zero.
- Operator producing the next partial solution must not be nul
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/e37ac94f6797a371.
Report an issue: GitHub.