apache/beam · error · IllegalArgumentException
Unable to determine accumulator coder for
Error message
Unable to determine accumulator coder for {} from {} What it means
StateSpecs.combiningFromInputInternal() infers the accumulator coder by calling CombineFn.getAccumulatorCoder() against the standard CoderRegistry. When the CombineFn cannot provide an accumulator coder given the input coder (CannotProvideCoderException), Beam wraps it in an IllegalArgumentException naming the CombineFn class and input coder. Without an accumulator coder the CombiningState cannot be serialized.
Solutions
- Override getAccumulatorCoder(CoderRegistry, Coder<InputT>) in your CombineFn and return an explicit accumulator coder.
- Register a CoderProvider for the accumulator type, or annotate the accumulator class with @DefaultCoder(...).
- Use the StateSpecs.combining(accumCoder, combineFn) overload that supplies the accumulator coder explicitly.
Example fix
// before
class MyFn extends CombineFn<Long, Accum, Long> { /* no getAccumulatorCoder */ }
// after
@Override
public Coder<Accum> getAccumulatorCoder(CoderRegistry registry, Coder<Long> inputCoder) {
return accumulatorCoder;
} Defensive patterns
Strategy: validation
Validate before calling
try {
combineFn.getAccumulatorCoder(CoderRegistry.createDefault(), inputCoder);
} catch (CannotProvideCoderException e) {
// supply an explicit accumulator coder via StateSpecs.combining(accumCoder, combineFn)
} Try / catch
try {
spec = StateSpecs.combining(combineFn);
} catch (IllegalArgumentException e) {
spec = StateSpecs.combining(explicitAccumCoder, combineFn);
} Prevention
- Always override getAccumulatorCoder() in custom CombineFns
- Register coders for accumulator types with @DefaultCoder or CoderRegistry#registerCoderProvider
- Prefer the explicit StateSpecs.combining(accumCoder, combineFn) overload in production code
When it happens
Trigger: Creating a state spec via StateSpecs.combining(getCombineFn()) (or combiningFromInputInternal internally) where the CombineFn's getAccumulatorCoder throws CannotProvideCoderException — typically a custom CombineFn lacking an accumulator CoderProvider or a generic accumulator type Beam cannot infer from the input coder.
Common situations: Custom CombineFn with an accumulator type not derivable (e.g. generic class AccumT without registerCoderProvider); using combine functions over custom input types without registered coders; Avro/POJO types missing @DefaultCoder annotations.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Bad coder for input of
- Bad coder for output of
- cannot encode a null Instant
- cannot encode a null Iterable
- cannot encode a null
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/c64a0e7b12570e6e.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/state/StateSpecs.java:304
/**
* <b><i>For internal use only; no backwards-compatibility guarantees.</i></b>
*
* <p>Create a state spec for values that use a {@link CombineFn} to automatically merge multiple
* {@code InputT}s into a single {@code OutputT}.
*
* <p>This determines the {@code Coder<AccumT>} from the given {@code Coder<InputT>}, and should
* only be used to initialize static values.
*/
@Internal
public static <InputT, AccumT, OutputT>
StateSpec<CombiningState<InputT, AccumT, OutputT>> combiningFromInputInternal(
Coder<InputT> inputCoder, CombineFn<InputT, AccumT, OutputT> combineFn) {
try {
Coder<AccumT> accumCoder = combineFn.getAccumulatorCoder(STANDARD_REGISTRY, inputCoder);
return combiningInternal(accumCoder, combineFn);
} catch (CannotProvideCoderException e) {
throw new IllegalArgumentException(
"Unable to determine accumulator coder for "
+ combineFn.getClass().getSimpleName()
+ " from "
+ inputCoder,
e);
}
}
private static <InputT, AccumT, OutputT>
StateSpec<CombiningState<InputT, AccumT, OutputT>> combiningInternal(
Coder<AccumT> accumCoder, CombineFn<InputT, AccumT, OutputT> combineFn) {
return new CombiningStateSpec<>(accumCoder, combineFn);
}
private static <InputT, AccumT, OutputT>
StateSpec<CombiningState<InputT, AccumT, OutputT>> combiningInternal(
Coder<AccumT> accumCoder, CombineFnWithContext<InputT, AccumT, OutputT> combineFn) {
return new CombiningWithContextStateSpec<>(accumCoder, combineFn);View on GitHub (pinned to 12126d8942)