apache/flink · critical · IllegalArgumentException
Unsupported type of window strategy : {strategyClass}
Error message
Unsupported type of window strategy : {strategyClass} What it means
WindowUtils.createWindowAssigner translates the user-facing WindowStrategy into a runtime WindowAssigner via an instanceof chain that recognizes exactly four classes: GlobalWindowStrategy, TumblingTimeWindowStrategy, SlidingTimeWindowStrategy and SessionWindowStrategy. Any other WindowStrategy instance falls through to IllegalArgumentException during job translation, before the job ever runs. Because the check is instanceof-based (not sealed), it also fails for same-named classes loaded from a different jar version.
Source
Thrown at flink-datastream/src/main/java/org/apache/flink/datastream/impl/extension/window/utils/WindowUtils.java:68
} else if (windowStrategy instanceof SlidingTimeWindowStrategy) {
return ((SlidingTimeWindowStrategy) windowStrategy).getAllowedLateness().toMillis();
} else {
return 0;
}
}
/** Create a {@link WindowAssigner} according to {@link WindowStrategy}. */
public static WindowAssigner<?, ?> createWindowAssigner(WindowStrategy windowStrategy) {
if (windowStrategy instanceof GlobalWindowStrategy) {
return createGlobalWindowAssigner();
} else if (windowStrategy instanceof TumblingTimeWindowStrategy) {
return createTumblingTimeWindowAssigner((TumblingTimeWindowStrategy) windowStrategy);
} else if (windowStrategy instanceof SlidingTimeWindowStrategy) {
return createSlidingTimeWindowAssigner((SlidingTimeWindowStrategy) windowStrategy);
} else if (windowStrategy instanceof SessionWindowStrategy) {
return createSessionWindowAssigner((SessionWindowStrategy) windowStrategy);
} else {
throw new IllegalArgumentException(
"Unsupported type of window strategy : " + windowStrategy.getClass());
}
}
/** Create window assigner for global window. */
private static WindowAssigner<?, ?> createGlobalWindowAssigner() {
return GlobalWindows.createWithEndOfStreamTrigger();
}
/** Create window assigner for tumbling time window. */
private static WindowAssigner<?, ?> createTumblingTimeWindowAssigner(
TumblingTimeWindowStrategy windowStrategy) {
switch (windowStrategy.getTimeType()) {
case PROCESSING:
return TumblingProcessingTimeWindows.of(windowStrategy.getWindowSize());
case EVENT:
return TumblingEventTimeWindows.of(windowStrategy.getWindowSize());
default:View on GitHub (pinned to 2f3c205e92)
Solutions
- Build strategies only via the WindowStrategy factories: global(), tumbling(...), sliding(...), session(...).
- Align flink-datastream-api and flink-dist versions in the project and on the cluster; inspect the fat jar and flink/lib for duplicate strategy classes.
- If custom windowing is required, use a WindowAssigner-based DataStream v1 window operator instead of subclassing WindowStrategy.
- Log windowStrategy.getClass().getName() and its ClassLoader in job setup to confirm the instance comes from the expected jar.
Example fix
// before: custom subclass the runtime cannot map
class MyWindowStrategy extends WindowStrategy {}
stream.process(fn, new MyWindowStrategy());
// after: built-in factory
class MyWindowStrategy extends WindowStrategy {}
stream.process(fn, WindowStrategy.tumbling(Duration.ofMinutes(1), WindowStrategy.EVENT_TIME)); Defensive patterns
Strategy: type-guard
Validate before calling
// reject unknown strategies at job composition time with a clear message
if (!isSupportedStrategy(strategy)) {
throw new IllegalArgumentException(
"Unsupported WindowStrategy: " + strategy.getClass().getName()
+ "; use WindowStrategy.global/tumbling/sliding/session");
}
stream.process(fn, strategy); Type guard
static boolean isSupportedStrategy(WindowStrategy s) {
return s instanceof GlobalWindowStrategy
|| s instanceof TumblingTimeWindowStrategy
|| s instanceof SlidingTimeWindowStrategy
|| s instanceof SessionWindowStrategy;
} Prevention
- Build strategies only via the WindowStrategy factory methods
- Keep flink-datastream-api and flink-dist on the same release; check fat jars for duplicates
- For custom windowing use the DataStream v1 WindowAssigner API instead of subclassing WindowStrategy
When it happens
Trigger: Passing anything but the four built-in strategies to a windowed DataStream v2 operator: a user subclass of WindowStrategy, an instance deserialized/built from a mismatched flink-datastream jar, or a plain 'new WindowStrategy()' base instance. The throw happens when the job graph is translated, i.e. at submit time in the client or JobManager.
Common situations: Developers extending WindowStrategy hoping to add custom windowing; mixed flink-datastream-api (client) and flink-dist (cluster) versions where the strategy class is duplicated; shading/relocation producing two copies of the strategy classes.
Related errors
- Unsupported time type : {}
- Window {window} is not in in-flight window set.
- The window uses a merging assigner, but the window state is
- The end timestamp of an event-time window cannot become earl
- The end timestamp of a processing-time window cannot become
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/57d0b5de8e6db969.
Report an issue: GitHub.