apache/beam · error · IOException

Could not obtain a Coder for the accumulator

Error message

Could not obtain a Coder for the accumulator

What it means

CombineTranslation.extractAccumulatorCoder asks the CombineFn for an accumulator Coder via getAccumulatorCoder; when the coder registry cannot provide one (CannotProvideCoderException), it wraps it in this IOException while converting the transform to its RunnerApi form.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/CombineTranslation.java:109

        // FunctionSpec.
        return null;
      }
    }

    private static <K, InputT, AccumT> Coder<AccumT> extractAccumulatorCoder(
        GlobalCombineFn<InputT, AccumT, ?> combineFn,
        AppliedPTransform<PCollection<KV<K, InputT>>, ?, Combine.PerKey<K, InputT, ?>> transform)
        throws IOException {
      try {
        @SuppressWarnings("unchecked")
        PCollection<KV<K, InputT>> mainInput =
            (PCollection<KV<K, InputT>>)
                Iterables.getOnlyElement(TransformInputs.nonAdditionalInputs(transform));
        return combineFn.getAccumulatorCoder(
            transform.getPipeline().getCoderRegistry(),
            ((KvCoder<K, InputT>) mainInput.getCoder()).getValueCoder());
      } catch (CannotProvideCoderException e) {
        throw new IOException("Could not obtain a Coder for the accumulator", e);
      }
    }
  }

  /** A {@link PTransformTranslation.TransformPayloadTranslator} for {@link Combine.Globally}. */
  public static class CombineGloballyPayloadTranslator
      implements PTransformTranslation.TransformPayloadTranslator<Combine.Globally<?, ?>> {
    private CombineGloballyPayloadTranslator() {}

    @Override
    public String getUrn() {
      return PTransformTranslation.COMBINE_GLOBALLY_TRANSFORM_URN;
    }

    @Override
    public FunctionSpec translate(
        AppliedPTransform<?, ?, Combine.Globally<?, ?>> transform, SdkComponents components)
        throws IOException {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Register a coder for the accumulator/value type: pipeline.getCoderRegistry().registerCoderForType(TypeDescriptor.of(MyAccum.class), MyAccumCoder::new)
  2. Implement getAccumulatorCoder properly or provide a CoderProvider via @AutoService CoderProviderRegistrar
  3. Ensure the main input PCollection carries a KvCoder with a concrete value coder
  4. Use pipeline.getCoderRegistry() verification (coderOf) before translation to test the lookup

Example fix

// before
Pipeline p = ...; // no registration for MyAccum
// after
p.getCoderRegistry().registerCoderForType(
    TypeDescriptor.of(MyAccum.class), new MyAccumCoder());
Defensive patterns

Strategy: validation

Validate before calling

Coder<K> valueCoder = ((KvCoder<K, InputT>) mainInput.getCoder()).getValueCoder();
pipeline.getCoderRegistry().getCoder(valueTypeDescriptor); // throws CannotProvideCoderException early if unresolvable

Try / catch

try {
  return CoderTranslation.toProto(transform, components);
} catch (IOException e) {
  if (e.getMessage().contains("Could not obtain a Coder for the accumulator")) {
    throw new IllegalStateException("register a coder for the accumulator/value type", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Translating a Combine.GloballyKeysSorted/PerKey transform whose main input is a KvCoder whose value type has no registered coder — e.g. a custom type never registered with the CoderRegistry, or input PCollections created without coders in a non-Java-created pipeline.

Common situations: Custom accumulator types without CoderProvider registration; values built with generics/anonymous classes the registry can't infer; pipelines deserialized from other SDKs then re-translated in Java.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/a6f2df2e7a53066c. Report an issue: GitHub.