apache/flink · error · UnsupportedOperationException
The end timestamp of a processing-time window cannot become
Error message
The end timestamp of a processing-time window cannot become earlier than the current processing time by merging. Current processing time: {processingTime} window: {mergeResult} What it means
Thrown from the MergeFunction callback inside OneInputWindowProcessOperator while a record is added to a processing-time session window. After merging, the resulting window's maxTimestamp must still be later than the current processing time (mergeResult.maxTimestamp() > currentProcessingTime); a merged session that would already be due for trigger/cleanup is refused rather than created in an already-expired state. The message names the current processing time and the offending mergeResult window.
Source
Thrown at flink-datastream/src/main/java/org/apache/flink/datastream/impl/extension/window/operators/OneInputWindowProcessOperator.java:265
if ((windowAssigner.isEventTime()
&& mergeResult.maxTimestamp() + allowedLateness
<= internalTimerService
.currentWatermark())) {
throw new UnsupportedOperationException(
"The end timestamp of an "
+ "event-time window cannot become earlier than the current watermark "
+ "by merging. Current event time: "
+ internalTimerService
.currentWatermark()
+ " window: "
+ mergeResult);
} else if (!windowAssigner.isEventTime()) {
long currentProcessingTime =
internalTimerService.currentProcessingTime();
if (mergeResult.maxTimestamp()
<= currentProcessingTime) {
throw new UnsupportedOperationException(
"The end timestamp of a "
+ "processing-time window cannot become earlier than the current processing time "
+ "by merging. Current processing time: "
+ currentProcessingTime
+ " window: "
+ mergeResult);
}
}
triggerContext.setKey(key);
triggerContext.setWindow(mergeResult);
triggerContext.onMerge(mergedWindows);
for (W m : mergedWindows) {
triggerContext.setWindow(m);
triggerContext.clear();
WindowUtils.deleteCleanupTimer(View on GitHub (pinned to 2f3c205e92)
Solutions
- Increase the session gap so gap > worst-case per-record delay (queueing + backpressure + GC) - the merged session then never expires before the merge completes.
- Fix the throughput problem: raise parallelism, reduce per-record work, check backpressure in the Web UI, enlarge network buffers.
- Prefer event-time session windows (WindowStrategy.session(gap, TimeType.EVENT)) when correctness must not depend on wall-clock pacing.
- In tests, drive processing-time windows with a controlled clock/pipelined input instead of sleeping between records.
Example fix
// before: gap smaller than queueing delay stream.process(windowFn, WindowStrategy.session(Duration.ofSeconds(2), WindowStrategy.PROCESSING_TIME)); // after: gap dominates worst-case end-to-end delay stream.process(windowFn, WindowStrategy.session(Duration.ofMinutes(1), WindowStrategy.PROCESSING_TIME));
Defensive patterns
Strategy: validation
Validate before calling
// fail fast at job setup: processing-time sessions need gap > worst-case record delay
long gapMs = sessionGap.toMillis();
if (gapMs <= measuredMaxRecordDelayMs) {
throw new IllegalArgumentException(
"processing-time session gap (" + gapMs + "ms) must exceed max record delay ("
+ measuredMaxRecordDelayMs + "ms)");
} Prevention
- Monitor backpressure; the session gap must dominate worst-case queueing delay
- Prefer event-time sessions where wall-clock pacing affects correctness
- Load-test processing-time session jobs at production throughput before deploying
When it happens
Trigger: WindowStrategy.session(gap, TimeType.PROCESSING): a record is assigned a session that merges with existing sessions into a window whose end (assignment time + gap) is <= current processing time at merge time. Happens when records spend longer than the session gap in queues (backpressure, slow source, GC pause, checkpoint stall) so wall-clock time overtakes the merged window's end.
Common situations: Session gap of a few seconds under backpressure or checkpoint stalls; bursty catch-up sources (file/Kafka after idle); overloaded TaskManagers where processing time outruns throughput; tests that pre-generate element timestamps and then replay them slower than real time.
Related errors
- The end timestamp of a processing-time window cannot become
- The end timestamp of a processing-time window cannot become
- 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
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/0e42b76bb19219dd.
Report an issue: GitHub.