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

  1. Increase watermark delay: use WatermarkStrategy.forBoundedOutOfOrderness(Duration) at least as large as the maximum expected event delay plus the session gap.
  2. 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.
  3. If session semantics are optional, switch to a non-merging assigner that supports lateness, e.g. WindowStrategy.tumbling(size, TimeType.EVENT, allowedLateness).
  4. 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

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


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/1c80a160a51ec09d. Report an issue: GitHub.