apache/flink · error · UnsupportedOperationException
The end timestamp of an event-time window cannot become earl
Error message
The end timestamp of an event-time window cannot become earlier than the current watermark by merging. Current event time: {eventTime} window: {mergeResult} What it means
Thrown from the MergeFunction callback inside OneInputWindowProcessOperator while a record is added to an event-time session window. When two in-flight sessions merge, the merged window's end timestamp (maxTimestamp) plus allowedLateness must still be later than the current watermark; otherwise the merged session would already be expired and its state possibly cleaned up, so Flink refuses the merge with UnsupportedOperationException. The message reports the current watermark ('Current event time') and the offending mergeResult window.
Source
Thrown at flink-datastream/src/main/java/org/apache/flink/datastream/impl/extension/window/operators/OneInputWindowProcessOperator.java:252
// is the merged window and we work with that. If we don't merge then
// actualWindow == window
W actualWindow =
mergingWindows.addWindow(
window,
new MergingWindowSet.MergeFunction<>() {
@Override
public void merge(
W mergeResult,
Collection<W> mergedWindows,
W stateWindowResult,
Collection<W> mergedStateWindows)
throws Exception {
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: "View on GitHub (pinned to 2f3c205e92)
Solutions
- Increase watermark delay: use WatermarkStrategy.forBoundedOutOfOrderness(Duration) at least as large as the maximum expected event delay plus the session gap.
- Drop or divert late records before the window operator (compare record timestamp with currentWatermark() in an upstream process function and route them to a side output) so they can never trigger a merge of expired sessions.
- If session semantics are optional, switch to a non-merging assigner that supports lateness, e.g. WindowStrategy.tumbling(size, TimeType.EVENT, allowedLateness).
- If late data must be merged into sessions, track upstream support for allowedLateness on session strategies; meanwhile consider the DataStream v1 WindowOperator which supports session windows with allowed lateness.
Example fix
// before: monotonic watermarks + event-time sessions -> late merges throw
WatermarkStrategy.<Event>forMonotonousTimestamps();
stream.process(windowFn, WindowStrategy.session(Duration.ofMinutes(10), WindowStrategy.EVENT_TIME));
// after: out-of-orderness budget >= max event delay (+ session gap headroom)
WatermarkStrategy.<Event>forBoundedOutOfOrderness(Duration.ofMinutes(15))
.withTimestampAssigner((e, ts) -> e.getEventTime()); Defensive patterns
Strategy: validation
Validate before calling
// upstream of the window operator: keep records that would merge into
// an already-expired session out of the windowed stream
long wm = ctx.currentWatermark();
if (event.timestamp() + sessionGapMs + maxDelayMs <= wm) {
ctx.output(LATE_DATA_TAG, event); // or drop
} else {
ctx.output(mainOutput, event);
} Prevention
- Size watermark out-of-orderness >= maximum event delay + session gap
- Never pair forMonotonousTimestamps with event-time session windows on out-of-order sources
- Add a late-data side output before windowed operators in production jobs
- Track watermark lag in metrics and re-tune the delay budget from measurements
When it happens
Trigger: An out-of-order record arrives for an event-time session window (WindowStrategy.session(gap, TimeType.EVENT)) when watermark W already satisfies mergeResult.maxTimestamp() + allowedLateness <= W: the late record would extend or merge sessions into a window whose end is at/before the watermark. Note the session() factory does not expose allowedLateness, so effectively any merge whose result expires at the current watermark throws.
Common situations: WatermarkStrategy with too little bounded out-of-orderness relative to the real event delay; session gap smaller than inter-event delay skew; sources replaying old data (Kafka rewind, backfill) after watermarks advanced; forMonotonousTimestamps combined with any out-of-order producer.
Related errors
- The end timestamp of an event-time window cannot become earl
- The end timestamp of an event-time window cannot become earl
- Window {window} is not in in-flight window set.
- The window uses a merging assigner, but the window state is
- 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/1c80a160a51ec09d.
Report an issue: GitHub.