apache/beam · error · UnsupportedOperationException
Please explicitly specify windowing in SQL query using HOP/T
Error message
Please explicitly specify windowing in SQL query using HOP/TUMBLE/SESSION functions (default trigger will be used in this case). Unbounded input with global windowing and default trigger is not supported in Beam SQL aggregations. See GroupByKey section in Beam Programming Guide
What it means
Beam SQL aggregations (GROUP BY) on unbounded (streaming) input require explicit windowing via HOP/TUMBLE/SESSION. Global windowing combined with the default trigger on an unbounded PCollection would be an invalid GroupByKey scenario per the Beam model, so validateWindowIsSupported throws UnsupportedOperationException before the pipeline even runs.
Source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamAggregationRel.java:343
.apply(Window.into(windowFn));
return windowedStream;
}
/**
* Performs the same check as {@link GroupByKey}, provides more context in exception.
*
* <p>Verifies that the input PCollection is bounded, or that there is windowing/triggering
* being used. Without this, the watermark (at end of global window) will never be reached.
*
* <p>Throws {@link UnsupportedOperationException} if validation fails.
*/
private void validateWindowIsSupported(PCollection<Row> upstream) {
WindowingStrategy<?, ?> windowingStrategy = upstream.getWindowingStrategy();
if (windowingStrategy.getWindowFn() instanceof GlobalWindows
&& windowingStrategy.getTrigger() instanceof DefaultTrigger
&& upstream.isBounded() != BOUNDED) {
throw new UnsupportedOperationException(
"Please explicitly specify windowing in SQL query using HOP/TUMBLE/SESSION functions "
+ "(default trigger will be used in this case). "
+ "Unbounded input with global windowing and default trigger is not supported "
+ "in Beam SQL aggregations. "
+ "See GroupByKey section in Beam Programming Guide");
}
}
static DoFn<Row, Row> mergeRecord(
Schema outputSchema,
int windowStartFieldIndex,
boolean ignoreValues,
boolean verifyRowValues) {
return new DoFn<Row, Row>() {
@ProcessElement
public void processElement(
@Element Row kvRow, BoundedWindow window, OutputReceiver<Row> o) {
int capacity =View on GitHub (pinned to 12126d8942)
Solutions
- Add an explicit window function to the aggregation: GROUP BY TUMBLE(eventTime, INTERVAL ...), HOP(...), or SESSION(...)
- Ensure the input PCollection has non-default windowing/trigger if you must keep global windows (e.g. set a non-default trigger)
- Make the input bounded if batch semantics are intended
- See the GroupByKey section of the Beam Programming Guide for why this combination is invalid
Example fix
// before SELECT f1, COUNT(*) FROM t GROUP BY f1 -- streaming, no windowing // after SELECT f1, COUNT(*) FROM t GROUP BY f1, TUMBLE(eventTime, INTERVAL '1' MINUTE)
Defensive patterns
Strategy: validation
Validate before calling
import org.apache.beam.sdk.transforms.windowing.*;
WindowingStrategy<?, ?> ws = upstream.getWindowingStrategy();
boolean ok = !(ws.getWindowFn() instanceof GlobalWindows
&& ws.getTrigger() instanceof DefaultTrigger
&& !pc.isBounded().equals(PCollection.IsBounded.BOUNDED));
if (!ok) throw new IllegalStateException("Specify HOP/TUMBLE/SESSION for streaming aggregation"); Type guard
boolean supportsSqlAggregation(PCollection<?> pc) {
WindowingStrategy<?, ?> ws = pc.getWindowingStrategy();
return pc.isBounded() == PCollection.IsBounded.BOUNDED
|| !(ws.getWindowFn() instanceof GlobalWindows
&& ws.getTrigger() instanceof DefaultTrigger);
} Try / catch
try {
result = stmt.executeSql(query);
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("explicitly specify windowing")) {
// rewrite query with TUMBLE/HOP/SESSION and re-run
} else throw e;
} Prevention
- Always include TUMBLE/HOP/SESSION in GROUP BY queries over streaming input
- Verify the input PCollection's windowing strategy before SQL aggregation
- Do not rely on default triggers for streaming aggregations; read the Beam GroupByKey programming guide
When it happens
Trigger: Executing a Beam SQL aggregation over an unbounded PCollection whose windowing strategy is GlobalWindows with DefaultTrigger and no HOP/TUMBLE/SESSION in the query.
Common situations: Streaming data (Kafka/Flink source) fed into a Beam SQL query that forgot the window function; queries written against bounded input then reused on streaming input; Beam 2.x default-trigger streaming semantics.
Related errors
- Unknown window function ${simpleName}
- inputs of ${opType} have different window strategy: ${leftWi
- FULL OUTER JOIN is not supported when join a bounded table w
- `ORDER BY` is only supported for %s, actual windowing strate
- Unsupported window mapping fn: ${sideInput.windowMappingFn.u
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f16a515afc3599a7.
Report an issue: GitHub.