apache/flink · error · RuntimeException
Cannot create accumulator ${accumulatorClass.getName()}
Error message
Cannot create accumulator ${accumulatorClass.getName()} What it means
Thrown by AbstractRuntimeUDFContext.getAccumulator(name, accumulatorClass) when the accumulatorClass cannot be instantiated via reflection (accumulatorClass.newInstance()). The most common cause is that the accumulator class lacks a public no-arg constructor, is abstract, or is an interface. The RuntimeException swallows the original exception (InstantiationException or IllegalAccessException).
Source
Thrown at flink-core/src/main/java/org/apache/flink/api/common/functions/util/AbstractRuntimeUDFContext.java:191
}
// --------------------------------------------------------------------------------------------
@SuppressWarnings("unchecked")
private <V, A extends Serializable> Accumulator<V, A> getAccumulator(
String name, Class<? extends Accumulator<V, A>> accumulatorClass) {
Accumulator<?, ?> accumulator = accumulators.get(name);
if (accumulator != null) {
AccumulatorHelper.compareAccumulatorTypes(
name, accumulator.getClass(), accumulatorClass);
} else {
// Create new accumulator
try {
accumulator = accumulatorClass.newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Cannot create accumulator " + accumulatorClass.getName());
}
accumulators.put(name, accumulator);
}
return (Accumulator<V, A>) accumulator;
}
@Override
@PublicEvolving
public <T> ValueState<T> getState(ValueStateDescriptor<T> stateProperties) {
throw new UnsupportedOperationException(
"This state is only accessible by functions executed on a KeyedStream");
}
@Override
@PublicEvolving
public <T> ListState<T> getListState(ListStateDescriptor<T> stateProperties) {
throw new UnsupportedOperationException(View on GitHub (pinned to 2f3c205e92)
Solutions
- Ensure your custom Accumulator class has a public no-arg constructor.
- If the accumulator needs parameters, use addAccumulator() to pre-construct and register it in open(), then retrieve it with getAccumulator(name) instead of passing the class.
- Verify you are passing a concrete class, not an interface or abstract type.
Example fix
// before — class has no no-arg constructor
public class MyCounter implements Accumulator<Long, Long> {
private final String label;
public MyCounter(String label) { this.label = label; }
}
getRuntimeContext().getAccumulator("c", MyCounter.class); // throws
// after — add a no-arg constructor and pre-register
public class MyCounter implements Accumulator<Long, Long> {
private String label = "default";
public MyCounter() {}
public MyCounter(String label) { this.label = label; }
}
// in open():
getRuntimeContext().addAccumulator("c", new MyCounter("custom")); Defensive patterns
Strategy: validation
Validate before calling
// Verify the class has a public no-arg constructor before passing it
try {
accumulatorClass.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Accumulator class must have a public no-arg constructor");
} Prevention
- Ensure custom Accumulator classes have a public no-arg constructor.
- Prefer addAccumulator() with a pre-built instance over getAccumulator(name, class) when the class needs parameters.
- Use concrete classes, not interfaces or abstract types, as the accumulatorClass argument.
When it happens
Trigger: A RichFunction calls getRuntimeContext().getAccumulator(name, accumulatorClass) with a class that cannot be reflectively instantiated — no public no-arg constructor, abstract class, interface, or a constructor that throws.
Common situations: Custom Accumulator subclass with only a parameterized constructor. Passing an interface type or abstract base class instead of a concrete implementation. Accumulator class whose constructor throws an exception during instance creation.
Related errors
- The accumulator '${name}' already exists and cannot be added
- The runtime context has not been initialized.
- This state is only accessible by functions executed on a Key
- The broadcast variable with name '${name}' is not a List. A
- The broadcast variable with name '${name}' has not been set.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/6a3547fa77af5e03.
Report an issue: GitHub.