apache/flink · error · IllegalStateException
The runtime context has not been initialized.
Error message
The runtime context has not been initialized.
What it means
Thrown by AbstractRichFunction.getRuntimeContext() when the Flink runtime has not yet injected the RuntimeContext via setRuntimeContext(). The runtime normally calls setRuntimeContext() before open(); calling getRuntimeContext() outside the Flink execution lifecycle (e.g. in a unit test, in a constructor, or in a static initializer) will trigger this.
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/functions/AbstractRichFunction.java:51
private static final long serialVersionUID = 1L;
// --------------------------------------------------------------------------------------------
// Runtime context access
// --------------------------------------------------------------------------------------------
private transient RuntimeContext runtimeContext;
@Override
public void setRuntimeContext(RuntimeContext t) {
this.runtimeContext = t;
}
@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
// --------------------------------------------------------------------------------------------
View on GitHub (pinned to 2f3c205e92)
Solutions
- Move all getRuntimeContext() calls inside the open() method or later lifecycle methods (map(), flatMap(), etc.), never in constructors or field initializers.
- In unit tests, wrap the RichFunction with a RuntimeUDFContext or use Flink's test utilities (e.g. KeyedOneInputStreamOperatorTestHarness or AbstractStreamOperatorTestHarness) that properly set the context.
- If you need runtime info during construction, defer it to open() and store it in a field there.
Example fix
// before
public class MyMapper extends RichMapFunction<String, String> {
private final Counter counter = getRuntimeContext().getMetricGroup().counter("myCounter");
}
// after — initialize in open()
public class MyMapper extends RichMapFunction<String, String> {
private transient Counter counter;
@Override
public void open(OpenContext ctx) throws Exception {
counter = getRuntimeContext().getMetricGroup().counter("myCounter");
}
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure getRuntimeContext() is only called from open() or processing methods // In tests, wrap the function properly: RichMapFunction<String, String> fn = new MyMapper(); fn.setRuntimeContext(new RuntimeUDFContext(...)); // use test utility // Then it is safe to call fn.getRuntimeContext()
Prevention
- Never call getRuntimeContext() in constructors or field initializers — only in open() or later lifecycle methods.
- In unit tests, use StreamingRuntimeContext or RuntimeUDFContext test helpers to set the context before calling methods that use it.
- Mark fields that depend on the runtime context as transient and initialize them in open().
When it happens
Trigger: A RichFunction subclass calls getRuntimeContext() before the Flink runtime has called setRuntimeContext(). This happens when: the function is instantiated and tested outside a Flink pipeline, getRuntimeContext() is called in the constructor or a field initializer, or the function is used in a way that bypasses the normal open() lifecycle.
Common situations: Unit tests that instantiate a RichFunction directly without wrapping it in a RuntimeUDFContext. Calling getRuntimeContext() in a constructor or instance initializer block. Using a RichFunction inside a custom source/sink that does not go through the standard operator lifecycle.
Related errors
- This stub is not part of an iteration step function.
- The accumulator '${name}' already exists and cannot be added
- Cannot create accumulator ${accumulatorClass.getName()}
- This state is only accessible by functions executed on a Key
- The broadcast variable with name '${name}' is not a List. A
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/0380cb572512dd68.
Report an issue: GitHub.