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

  1. Ensure your custom Accumulator class has a public no-arg constructor.
  2. 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.
  3. 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

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


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