apache/beam · error · UnsupportedOperationException
%s is splittable and uses state, but these are not compatibl
Error message
%s is splittable and uses state, but these are not compatible
What it means
ParDo.validate inspects the DoFn signature at pipeline construction time and rejects DoFns that both declare state and are splittable, because Beam's model considers splitting an element incompatible with per-element state semantics. The transform cannot be built and construction fails with UnsupportedOperationException.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java:618
methodSignature.windowT().isSupertypeOf(actualWindowT),
"%s unable to provide window -- expected window type from parameter (%s) is not a "
+ "supertype of actual window type assigned by windowing (%s)",
methodSignature.targetMethod(),
methodSignature.windowT(),
actualWindowT);
}
}
/**
* Perform common validations of the {@link DoFn}, for example ensuring that state is used
* correctly and that its features can be supported.
*/
private static <InputT, OutputT> void validate(DoFn<InputT, OutputT> fn) {
DoFnSignature signature = DoFnSignatures.getSignature((Class) fn.getClass());
// State is semantically incompatible with splitting
if (!signature.stateDeclarations().isEmpty() && signature.processElement().isSplittable()) {
throw new UnsupportedOperationException(
String.format(
"%s is splittable and uses state, but these are not compatible",
fn.getClass().getName()));
}
// Timers are semantically incompatible with splitting
if ((!signature.timerDeclarations().isEmpty() || !signature.timerFamilyDeclarations().isEmpty())
&& signature.processElement().isSplittable()) {
throw new UnsupportedOperationException(
String.format(
"%s is splittable and uses timers, but these are not compatible",
fn.getClass().getName()));
}
// TimerFamily is semantically incompatible with splitting
if (!signature.timerFamilyDeclarations().isEmpty()
&& signature.processElement().isSplittable()) {
throw new UnsupportedOperationException(View on GitHub (pinned to 12126d8942)
Solutions
- Remove the state declarations from the splittable DoFn, or remove splittable processing (RestrictionTracker) from the stateful DoFn
- Split the logic into two DoFns: a splittable one producing elements, then a separate stateful ParDo
- Restructure to track progress via the restriction itself rather than persistent state
Example fix
// before
class Sdf extends DoFn<T, O> { @StateId ... ; @ProcessElement ProcessContinuation processElement(RestrictionTracker r, ...) }
// after
class Sdf extends DoFn<T, O> { @ProcessElement ProcessContinuation processElement(RestrictionTracker r, ...) } // state moved to downstream stateful DoFn Defensive patterns
Strategy: validation
Validate before calling
DoFnSignature sig = DoFnSignatures.getSignature((Class) fn.getClass());
if (!sig.stateDeclarations().isEmpty() && sig.processElement().isSplittable()) {
throw new IllegalArgumentException(fn.getClass() + " cannot use state and be splittable");
} Type guard
boolean stateAndSplittable(DoFn<?, ?> fn) {
DoFnSignature sig = DoFnSignatures.getSignature((Class) fn.getClass());
return !sig.stateDeclarations().isEmpty() && sig.processElement().isSplittable();
} Try / catch
try {
pipeline.apply(ParDo.of(fn));
} catch (UnsupportedOperationException e) {
if (e.getMessage() != null && e.getMessage().endsWith("splittable and uses state, but these are not compatible")) {
throw new IllegalStateException("Split into splittable read + separate stateful ParDo", e);
}
throw e;
} Prevention
- Review DoFn signatures before combining state with RestrictionTracker usage
- Keep stateful logic in non-splittable DoFns
- Add pipeline-construction unit tests that catch validate() errors early
When it happens
Trigger: Calling ParDo.of(fn) (which invokes validate) where fn's class declares @StateId fields AND its @ProcessElement is splittable (has a RestrictionTracker / @GetInitialRestriction watermarks etc.).
Common situations: Adding @StateId to an existing splittable DoFn (e.g. a file/splittable reader DoFn) assuming state works; combining libraries' SDF patterns with stateful processing.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Unable to infer a coder for ValueState and no Coder was spec
- Unable to infer a coder for CombiningState and no Coder was
- Unable to infer a coder for CombiningWithContextState and no
- Unable to infer a coder for BagState and no Coder was specif
- Unable to infer a coder for OrderedListState and no Coder wa
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/c02430a018f3a418.
Report an issue: GitHub.