apache/beam · error · RuntimeException
Unable to get state coder
Error message
Unable to get state coder
What it means
OrderedEventProcessor.expand() requests the state type StateT coder via handler.getStateCoder(pipeline). Unlike key/event coders it is not inferred from the input PCollection, so if the handler cannot supply one (CannotProvideCoderException), this RuntimeException is thrown. State must be serializable because Beam persists per-key state and buffers.
Solutions
- Provide an explicit state coder when constructing the handler/builder (e.g. usingSerializableCoder/AvroCoder supplier).
- Annotate the state class with @DefaultCoder or register a CoderProvider in the pipeline's CoderRegistry.
- Override getStateCoder in a handler subclass to return a concrete Coder<StateT>.
- Check that the StateT generic parameter is concrete at the call site.
Example fix
// before OrderedEventProcessor<KeyT, EventT, StateT, ...> p = OrderedEventProcessor.builder(handler)...build(); // after (handler supplies coder) OrderedEventProcessor.Builder<...> b = OrderedEventProcessor.builder(handlerWithStateCoder(SerializableCoder.of(MyState.class)));
Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(stateCoderSupplier, "state coder supplier must be configured on the handler before build()");
Type guard
static <StateT> boolean stateCoderConfigured(ComposedAccumulatingProcessingHandler<?, ?, StateT, ?, ?> h) {
try { return h.getStateCoder(pipeline) != null; } catch (CannotProvideCoderException e) { return false; }
} Try / catch
try {
handler.getStateCoder(pipeline);
} catch (CannotProvideCoderException e) {
throw new IllegalStateException("Provide an explicit Coder<StateT> in the handler configuration", e);
} Prevention
- Configure the state coder explicitly when building the handler
- Keep state classes simple and codable (Avro/Serializable)
- Test pipeline expansion in CI to catch missing coders early
When it happens
Trigger: Building OrderedEventProcessor with a state class that has no registered coder provider and no explicit coder configured on the handler; calling expand() where getStateCoder relies on type inference that fails for the custom StateT.
Common situations: State classes without @DefaultCoder or CoderProvider registration; using nested generic state types whose TypeDescriptor cannot be materialized; forgetting to pass a coder supplier when constructing the handler.
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
- set or map state type
- Unable to get event coder
- Unable to get key coder
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9eea0ed822371c22.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/ordered/src/main/java/org/apache/beam/sdk/extensions/ordered/OrderedEventProcessor.java:130
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 =
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>View on GitHub (pinned to 12126d8942)