apache/beam · error · RuntimeException
Unable to get event coder
Error message
Unable to get event coder
What it means
OrderedEventProcessor.expand() obtains a Coder for the event value type EventT via handler.getEventCoder(pipeline, input.getCoder()). When the coder cannot be inferred from the input's KvCoder, it wraps CannotProvideCoderException in this RuntimeException. Beam needs the event coder to serialize events (including unprocessed-event buffering) across stages.
Solutions
- Set an explicit KvCoder on the input PCollection with setCoder(KvCoder.of(keyCoder, eventCoder)) before expand().
- Annotate the event class with @DefaultCoder(AvroCoder.class) or register a CoderProvider in CoderRegistry.
- Override getEventCoder in your handler to return an explicit coder.
- Verify the generic type parameters of the PCollection are concrete, not type-erased.
Example fix
// before PCollection<KV<String, MyEvent>> in = ...; // after PCollection<KV<String, MyEvent>> in = in.setCoder(KvCoder.of(StringUtf8Coder.of(), AvroCoder.of(MyEvent.class)));
Defensive patterns
Strategy: validation
Validate before calling
if (!(input.getCoder() instanceof KvCoder)) {
throw new IllegalArgumentException("set KvCoder.of(keyCoder, eventCoder) on the input before expand()");
} Type guard
static boolean hasValueCoder(PCollection<?> pc) {
return pc.getCoder() instanceof KvCoder && ((KvCoder<?, ?>) pc.getCoder()).getValueCoder() != null;
} Try / catch
try {
processor.expand(input);
} catch (RuntimeException e) {
if (e.getCause() instanceof CannotProvideCoderException) {
input.setCoder(KvCoder.of(keyCoder, AvroCoder.of(EventT.class)));
processor.expand(input);
} else { throw e; }
} Prevention
- Annotate event POJOs with @DefaultCoder
- Set explicit coders on every PCollection feeding the processor
- Keep generic type parameters concrete (avoid raw types)
When it happens
Trigger: expand() applied to a PCollection<KV<EventKeyT, EventT>> whose value coder is unresolvable: value type is a custom class with no CoderProvider, input built via Create.of with erased generics, or coder inference throws CannotProvideCoderException in getEventCoder.
Common situations: Custom event POJOs lacking @DefaultCoder or a registered CoderProvider; using types like Object or raw generics; beam coder inference failing after a refactor changed the value type.
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
- Unable to get key coder
- ApproximateUnique.PerKey requires its input to use KvCoder
- cannot encode a null BitSet
- cannot encode a null byte[]
- cannot encode a null Integer
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/e09fa1bea12098d3.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/ordered/src/main/java/org/apache/beam/sdk/extensions/ordered/OrderedEventProcessor.java:123
final TupleTag<KV<EventKeyT, KV<Long, UnprocessedEvent<EventT>>>> unprocessedEventOutput =
new TupleTag<KV<EventKeyT, KV<Long, UnprocessedEvent<EventT>>>>("unprocessed-events") {};
OrderedProcessingHandler<EventT, EventKeyT, StateT, ResultT> handler = getHandler();
Pipeline pipeline = input.getPipeline();
Coder<EventKeyT> keyCoder;
try {
keyCoder = handler.getKeyCoder(pipeline, input.getCoder());
} catch (CannotProvideCoderException e) {
throw new RuntimeException("Unable to get key coder", e);
}
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 =View on GitHub (pinned to 12126d8942)