apache/flink · error · IllegalStateException

This stub is not part of an iteration step function.

Error message

This stub is not part of an iteration step function.

What it means

Thrown by AbstractRichFunction.getIterationRuntimeContext() when a RuntimeContext exists but is not an IterationRuntimeContext. This means the function is executing in a normal (non-iteration) streaming or batch context, but the code attempted to access iteration-specific features like iteration aggregators or brokered state.

Source

Thrown at flink-core/src/main/java/org/apache/flink/api/common/functions/AbstractRichFunction.java:62

    }

    @Override
    public RuntimeContext getRuntimeContext() {
        if (this.runtimeContext != null) {
            return this.runtimeContext;
        } else {
            throw new IllegalStateException("The runtime context has not been initialized.");
        }
    }

    @Override
    public IterationRuntimeContext getIterationRuntimeContext() {
        if (this.runtimeContext == null) {
            throw new IllegalStateException("The runtime context has not been initialized.");
        } else if (this.runtimeContext instanceof IterationRuntimeContext) {
            return (IterationRuntimeContext) this.runtimeContext;
        } else {
            throw new IllegalStateException("This stub is not part of an iteration step function.");
        }
    }

    // --------------------------------------------------------------------------------------------
    //  Default life cycle methods
    // --------------------------------------------------------------------------------------------

    @Override
    public void open(OpenContext openContext) throws Exception {}

    @Override
    public void close() throws Exception {}
}

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Remove the getIterationRuntimeContext() call if the function is not used inside an iterate() / closeWith() block.
  2. If the function is meant for an iteration, ensure it is wired into the iteration step via DataSet.iterate() / DataStream.iterate() and that the job graph actually builds an iteration.
  3. Use instanceof or try-catch to make the iteration-context access optional if the function is shared between iteration and non-iteration pipelines.

Example fix

// before
IterationRuntimeContext ctx = getIterationRuntimeContext();
// throws if not in iteration

// after — guard with type check
if (getRuntimeContext() instanceof IterationRuntimeContext) {
    IterationRuntimeContext ctx = getIterationRuntimeContext();
    // iteration-specific logic
} else {
    // fallback for non-iteration usage
}
Defensive patterns

Strategy: type-guard

Type guard

if (getRuntimeContext() instanceof IterationRuntimeContext) {
    IterationRuntimeContext ctx = getIterationRuntimeContext();
    // iteration-specific logic
}

Prevention

When it happens

Trigger: A RichFunction used inside a regular DataStream (no iterate() call) invokes getIterationRuntimeContext(). The runtime set a StreamingRuntimeContext or a plain RuntimeContext, neither of which implements IterationRuntimeContext.

Common situations: A step function from a Flink iteration is accidentally reused in a non-iteration pipeline. Copying code from an iteration-based job into a regular streaming job without removing iteration-specific calls. Using the legacy delta iteration API incorrectly.

Related errors


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