{"record":{"id":"e51aa09bed66dfa0","repo":"apache/flink","slug":"the-end-timestamp-of-a-processing-time-window-cann-e51aa0","errorCode":null,"errorMessage":"The end timestamp of a processing-time window cannot become earlier than the current processing time by merging. Current processing time: {processingTime} window: {mergeResult}","messagePattern":"The end timestamp of a processing-time window cannot become earlier than the current processing time by merging\\. Current processing time: (.+?) window: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"flink-datastream/src/main/java/org/apache/flink/datastream/impl/extension/window/operators/TwoOutputWindowProcessOperator.java","lineNumber":274,"sourceCode":"\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: \"\n                                                                + mergeResult);\n                                            }\n                                        }\n\n                                        triggerContext.setKey(key);\n                                        triggerContext.setWindow(mergeResult);\n\n                                        triggerContext.onMerge(mergedWindows);\n\n                                        for (W m : mergedWindows) {\n                                            triggerContext.setWindow(m);\n                                            triggerContext.clear();\n                                            WindowUtils.deleteCleanupTimer(","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-datastream/src/main/java/org/apache/flink/datastream/impl/extension/window/operators/TwoOutputWindowProcessOperator.java#L256-L292","documentation":"Thrown from the MergeFunction callback in TwoOutputWindowProcessOperator while a record is added to a processing-time session window. The merged window must end strictly after the current processing time; a session that would already be at/past wall clock when created is refused with UnsupportedOperationException instead of being born expired.","triggerScenarios":"WindowStrategy.session(gap, TimeType.PROCESSING): a record delayed longer than the session gap (backpressure, slow source, GC/checkpoint stall) merges sessions into a window whose maxTimestamp is <= current processing time at merge time.","commonSituations":"Small gaps under load; overloaded TaskManagers; bursty catch-up sources; tests replaying pre-timestamped records slower than wall clock.","solutions":["Raise the session gap above the worst-case observed per-record delay.","Eliminate the backpressure/stall source (parallelism, per-record cost, GC tuning).","Move to event-time sessions when wall-clock pacing is unacceptable.","Load-test before deploying processing-time sessions."],"exampleFix":"// before\nstream.process(twoOutputFn, WindowStrategy.session(Duration.ofSeconds(2), WindowStrategy.PROCESSING_TIME));\n// after\nstream.process(twoOutputFn, WindowStrategy.session(Duration.ofMinutes(1), WindowStrategy.PROCESSING_TIME));","handlingStrategy":"validation","validationCode":"// setup check: processing-time session gap vs worst-case record delay\nif (sessionGap.toMillis() <= maxRecordDelayMs) {\n    throw new IllegalArgumentException(\n            \"session gap (\" + sessionGap + \") must exceed max record delay (\" + maxRecordDelayMs + \"ms)\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Raise the session gap above measured worst-case delay before deploying","Address backpressure and stalls instead of shrinking gaps","Prefer event-time sessions under variable load"],"tags":["flink","datastream-v2","windowing","session-windows","two-output","processing-time","backpressure"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}