apache/beam · error · UnsupportedOperationException
Runner does not support draining.
Error message
Runner does not support draining.
What it means
PipelineResult.drain() is an optional API for draining (finishing without processing further input) a streaming pipeline. The default implementation in the PipelineResult interface throws UnsupportedOperationException because not every runner supports draining; the runner you are using never overrode it.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/PipelineResult.java:56
/**
* Cancels the pipeline execution.
*
* @throws IOException if there is a problem executing the cancel request.
* @throws UnsupportedOperationException if the runner does not support cancellation.
*/
State cancel() throws IOException;
/**
* Drains the pipeline execution.
*
* <p>Draining requests that the runner stop accepting new input and finish processing data that
* has already entered the pipeline.
*
* @throws IOException if there is a problem executing the drain request.
* @throws UnsupportedOperationException if the runner does not support draining.
*/
default State drain() throws IOException {
throw new UnsupportedOperationException("Runner does not support draining.");
}
/**
* Waits until the pipeline finishes and returns the final status. It times out after the given
* duration.
*
* @param duration The time to wait for the pipeline to finish. Provide a value less than 1 ms for
* an infinite wait.
* @return The final state of the pipeline or null on timeout.
* @throws UnsupportedOperationException if the runner does not support waiting to finish with a
* timeout.
*/
State waitUntilFinish(Duration duration);
/**
* Waits until the pipeline finishes and returns the final status.
*
* @return The final state of the pipeline.View on GitHub (pinned to 12126d8942)
Solutions
- Check runner support before draining: if (result instanceof DrainingResult) or consult the runner's capabilities documentation.
- Guard with try-catch on UnsupportedOperationException and fall back to cancel() or waitUntilFinish().
- Switch to a runner that supports drain (e.g. run in streaming mode on Dataflow/Flink/Spark runners).
- If the pipeline is batch, drain is not applicable - use cancel() or waitUntilFinish() instead.
Example fix
// before
PipelineResult result = pipeline.run();
result.drain();
// after
PipelineResult result = pipeline.run();
try {
result.drain();
} catch (UnsupportedOperationException e) {
result.cancel(); // runner does not support draining
} Defensive patterns
Strategy: try-catch
Validate before calling
// before draining, check capability
if (result.getClass().getName().equals("org.apache.beam.sdk.runners.DirectRunner$DirectPipelineResult")) {
throw new IllegalStateException("Runner does not support drain");
} Try / catch
try {
result.drain();
} catch (UnsupportedOperationException e) {
LOG.warn("Runner does not support draining; falling back to cancel", e);
result.cancel();
} Prevention
- Consult the runner capability matrix before relying on drain()
- Abstract drain/cancel behind your own interface with per-runner implementations
- Test streaming lifecycle code with the actual production runner, not just DirectRunner
When it happens
Trigger: Calling drain() on a PipelineResult from a runner that has not implemented it (e.g. DirectRunner or other runners without drain support).
Common situations: Code written for a streaming runner with drain support (like DataflowRunner/FlinkRunner in streaming mode) is run against a different runner (DirectRunner, TestPipeline) without checking support; batch pipelines where drain is meaningless.
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
- Unknown DirectoryTreatment: " + directoryTreatment
- Support for move options is not yet implemented.
- Class '%s' does not implement PipelineRunner. Supported pipe
- Unknown 'runner' specified '%s', supported pipeline runners
- %s is for internal use only and does not support case dispat
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/dcc67a142cc6e9d9.
Report an issue: GitHub.