{"record":{"id":"1c80a160a51ec09d","repo":"apache/flink","slug":"the-end-timestamp-of-an-event-time-window-cannot-b","errorCode":null,"errorMessage":"The end timestamp of an event-time window cannot become earlier than the current watermark by merging. Current event time: {eventTime} window: {mergeResult}","messagePattern":"The end timestamp of an event-time window cannot become earlier than the current watermark by merging\\. Current event time: (.+?) window: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink-datastream/src/main/java/org/apache/flink/datastream/impl/extension/window/operators/OneInputWindowProcessOperator.java","lineNumber":252,"sourceCode":"                // is the merged window and we work with that. If we don't merge then\n                // actualWindow == window\n                W actualWindow =\n                        mergingWindows.addWindow(\n                                window,\n                                new MergingWindowSet.MergeFunction<>() {\n                                    @Override\n                                    public void merge(\n                                            W mergeResult,\n                                            Collection<W> mergedWindows,\n                                            W stateWindowResult,\n                                            Collection<W> mergedStateWindows)\n                                            throws Exception {\n\n                                        if ((windowAssigner.isEventTime()\n                                                && mergeResult.maxTimestamp() + allowedLateness\n                                                        <= internalTimerService\n                                                                .currentWatermark())) {\n                                            throw new UnsupportedOperationException(\n                                                    \"The end timestamp of an \"\n                                                            + \"event-time window cannot become earlier than the current watermark \"\n                                                            + \"by merging. Current event time: \"\n                                                            + internalTimerService\n                                                                    .currentWatermark()\n                                                            + \" window: \"\n                                                            + mergeResult);\n                                        } else if (!windowAssigner.isEventTime()) {\n                                            long currentProcessingTime =\n                                                    internalTimerService.currentProcessingTime();\n                                            if (mergeResult.maxTimestamp()\n                                                    <= currentProcessingTime) {\n                                                throw new UnsupportedOperationException(\n                                                        \"The end timestamp of a \"\n                                                                + \"processing-time window cannot become earlier than the current processing time \"\n                                                                + \"by merging. Current processing time: \"\n                                                                + currentProcessingTime\n                                                                + \" window: \"","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-datastream/src/main/java/org/apache/flink/datastream/impl/extension/window/operators/OneInputWindowProcessOperator.java#L234-L270","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: monotonic watermarks + event-time sessions -> late merges throw\nWatermarkStrategy.<Event>forMonotonousTimestamps();\nstream.process(windowFn, WindowStrategy.session(Duration.ofMinutes(10), WindowStrategy.EVENT_TIME));\n// after: out-of-orderness budget >= max event delay (+ session gap headroom)\nWatermarkStrategy.<Event>forBoundedOutOfOrderness(Duration.ofMinutes(15))\n        .withTimestampAssigner((e, ts) -> e.getEventTime());","handlingStrategy":"validation","validationCode":"// upstream of the window operator: keep records that would merge into\n// an already-expired session out of the windowed stream\nlong wm = ctx.currentWatermark();\nif (event.timestamp() + sessionGapMs + maxDelayMs <= wm) {\n    ctx.output(LATE_DATA_TAG, event); // or drop\n} else {\n    ctx.output(mainOutput, event);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["flink","datastream-v2","windowing","session-windows","event-time","watermark","late-data"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}