apache/beam · error · RuntimeException
Unable to get result coder
Error message
Unable to get result coder
What it means
OrderedEventProcessor.expand() obtains the result coder via handler.getResultCoder(pipeline); a CannotProvideCoderException is rethrown as this RuntimeException. The result coder is required to build the KvCoder for the processor's main output PCollection<KV<EventKeyT, ResultT>>.
Solutions
- Configure an explicit result coder on the handler (coder supplier for ResultT) at construction time.
- Register a CoderProvider or add @DefaultCoder to the result class.
- Override getResultCoder in the handler to return a concrete coder.
- Verify ResultT's TypeDescriptor resolves to a concrete class.
Example fix
// before handler -> coder inference fails for MyResult // after .setCoderForType(TypeDescriptor.of(MyResult.class), AvroCoder.of(MyResult.class)) // or @DefaultCoder(AvroCoder.class) on MyResult
Defensive patterns
Strategy: validation
Validate before calling
try {
handler.getResultCoder(pipeline);
} catch (CannotProvideCoderException e) {
throw new IllegalStateException("ResultT needs a registered coder; add @DefaultCoder or a coder supplier", e);
} Type guard
static <ResultT> boolean resultCoderResolvable(ComposedAccumulatingProcessingHandler<?, ?, ?, ResultT, ?> h, Pipeline p) {
try { h.getResultCoder(p); return true; } catch (CannotProvideCoderException e) { return false; }
} Try / catch
try {
pipeline.apply(processor);
} catch (RuntimeException e) {
if (e.getCause() instanceof CannotProvideCoderException) {
throw new IllegalStateException("Set an explicit result coder for ResultT", e);
}
throw e;
} Prevention
- Register coders for every type parameter used in the processor
- Prefer concrete result classes over generics-inferred ones
- Run a smoke-test pipeline before production deployment
When it happens
Trigger: expand() invoked with a handler whose ResultT type has no inferable coder — custom result class without a CoderProvider, erased generics, or a handler implementation that delegates to coder inference which throws CannotProvideCoderException.
Common situations: Custom result types (e.g. user-defined processing outcome records) without coder registration; changing the ResultT type parameter without updating coder configuration; running on a runner requiring coders earlier than expected.
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
- ApproximateUnique.PerKey requires its input to use KvCoder
- Could not encode the default value
- Unable to get event coder
- Unable to get key coder
- Unable to get state coder
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/77660a4e16e55158.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/ordered/src/main/java/org/apache/beam/sdk/extensions/ordered/OrderedEventProcessor.java:137
Coder<EventT> eventCoder;
try {
eventCoder = handler.getEventCoder(pipeline, input.getCoder());
} catch (CannotProvideCoderException e) {
throw new RuntimeException("Unable to get event coder", e);
}
Coder<StateT> stateCoder;
try {
stateCoder = handler.getStateCoder(pipeline);
} catch (CannotProvideCoderException e) {
throw new RuntimeException("Unable to get state coder", e);
}
Coder<ResultT> resultCoder;
try {
resultCoder = handler.getResultCoder(pipeline);
} catch (CannotProvideCoderException e) {
throw new RuntimeException("Unable to get result coder", e);
}
KvCoder<EventKeyT, ResultT> mainOutputCoder = KvCoder.of(keyCoder, resultCoder);
KvCoder<EventKeyT, OrderedProcessingStatus> processingStatusCoder =
KvCoder.of(keyCoder, getOrderedProcessingStatusCoder(pipeline));
KvCoder<EventKeyT, KV<Long, UnprocessedEvent<EventT>>> unprocessedEventsCoder =
KvCoder.of(
keyCoder, KvCoder.of(VarLongCoder.of(), new UnprocessedEventCoder<>(eventCoder)));
if (handler instanceof OrderedProcessingGlobalSequenceHandler) {
OrderedProcessingGlobalSequenceHandler<EventT, EventKeyT, StateT, ResultT>
globalSequenceHandler =
(OrderedProcessingGlobalSequenceHandler<EventT, EventKeyT, StateT, ResultT>) handler;
return expandGlobalSequenceProcessing(
input,
mainOutput,
statusOutput,View on GitHub (pinned to 12126d8942)