apache/beam · error · UnsupportedOperationException

Output from FinishBundle for SDF is not supported in naive i

Error message

Output from FinishBundle for SDF is not supported in naive implementation

What it means

SplittableParDoNaiveBounded's FinishBundle output receiver does not support emitting elements when a bundle finishes. The naive SDF implementation only supports output during ProcessElement, so any attempt to emit from finishBundle is rejected. This is an intentional limitation of this portability fallback path.

Source

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

    }

    @FinishBundle
    public void finishBundle(FinishBundleContext c) {
      invoker.invokeFinishBundle(
          new BaseArgumentProvider<InputT, OutputT>() {
            @Override
            public DoFn<InputT, OutputT>.FinishBundleContext finishBundleContext(
                DoFn<InputT, OutputT> doFn) {
              return new DoFn<InputT, OutputT>.FinishBundleContext() {
                @Override
                public PipelineOptions getPipelineOptions() {
                  return c.getPipelineOptions();
                }

                @Override
                public void output(
                    @Nullable OutputT output, Instant timestamp, BoundedWindow window) {
                  throw new UnsupportedOperationException(
                      "Output from FinishBundle for SDF is not supported in naive implementation");
                }

                @Override
                public <T> void output(
                    TupleTag<T> tag, T output, Instant timestamp, BoundedWindow window) {
                  throw new UnsupportedOperationException(
                      "Output from FinishBundle for SDF is not supported in naive implementation");
                }
              };
            }

            @Override
            public PipelineOptions pipelineOptions() {
              return c.getPipelineOptions();
            }

            @Override

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove the c.output(...) call from the @FinishBundle method and emit elements during @ProcessElement instead
  2. Use a runner/translation that fully supports SDF finishBundle output instead of the naive implementation
  3. Restructure the pipeline so pending outputs are buffered and emitted in the next processElement invocation

Example fix

// before
@FinishBundle
public void finish(FinishBundleContext c) {
  c.output(result, timestamp, window); // throws
}
// after
@ProcessElement
public void process(ProcessContext c) {
  emitBuffered(c); // emit only from processElement
}
Defensive patterns

Strategy: validation

Validate before calling

if (doFn.getClass().getDeclaredMethodsWithAnnotation(FinishBundle.class).length > 0
    && finishBundleEmitsOutput(doFn)) {
  throw new IllegalStateException("FinishBundle must not emit output under naive SDF implementation");
}

Try / catch

try { pipeline.run(); } catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("FinishBundle for SDF")) { /* restructure DoFn to emit in ProcessElement */ }
  else throw e;
}

Prevention

When it happens

Trigger: A DoFn using @FinishBundle that calls c.output(...) while being executed via the naive bounded SDF translation path (e.g. a runner using SplittableParDoNaiveBounded for splittable DoFns).

Common situations: Running an SDF pipeline on a runner that falls back to the naive SplittableParDo implementation; a DoFn emits final aggregation results in finishBundle and is accidentally turned into an SDF (e.g. via splittable DoFn annotations or runner translation).

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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