{"record":{"id":"959d05d91b9276d1","repo":"apache/beam","slug":"cannot-output-with-timestamp-s-output-timestamps-must-be-no","errorCode":null,"errorMessage":"Cannot output with timestamp %s. Output timestamps must be no earlier than the timestamp of the current input (%s) minus the allowed skew (%s) and no later than %s. See the DoFn#getAllowedTimestampSkew() Javadoc for details on changing the allowed skew.","messagePattern":"Cannot output with timestamp (.+?)\\. Output timestamps must be no earlier than the timestamp of the current input \\((.+?)\\) minus the allowed skew \\((.+?)\\) and no later than (.+?)\\. See the DoFn#getAllowedTimestampSkew\\(\\) Javadoc for details on changing the allowed skew\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java","lineNumber":1573,"sourceCode":"          boundedWindow,\n          elementTimestampOrTimerHoldTimestamp,\n          elementTimestampOrTimerFireTimestamp,\n          paneInfo,\n          timeDomain);\n    }\n  }\n\n  @SuppressWarnings(\"deprecation\") // Allowed Skew is deprecated for users, but must be respected\n  private void checkTimestamp(Instant timestamp) {\n    Instant lowerBound;\n    try {\n      lowerBound = currentElement.getTimestamp().minus(doFn.getAllowedTimestampSkew());\n    } catch (ArithmeticException e) {\n      lowerBound = BoundedWindow.TIMESTAMP_MIN_VALUE;\n    }\n\n    if (timestamp.isBefore(lowerBound) || timestamp.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE)) {\n      throw new IllegalArgumentException(\n          String.format(\n              \"Cannot output with timestamp %s. Output timestamps must be no earlier than the \"\n                  + \"timestamp of the current input (%s) minus the allowed skew (%s) and no later \"\n                  + \"than %s. See the DoFn#getAllowedTimestampSkew() Javadoc for details on \"\n                  + \"changing the allowed skew.\",\n              timestamp,\n              currentElement.getTimestamp(),\n              doFn.getAllowedTimestampSkew().getMillis() >= Integer.MAX_VALUE\n                  ? doFn.getAllowedTimestampSkew()\n                  : PeriodFormat.getDefault().print(doFn.getAllowedTimestampSkew().toPeriod()),\n              BoundedWindow.TIMESTAMP_MAX_VALUE));\n    }\n  }\n\n  private class StartBundleArgumentProvider extends BaseArgumentProvider<InputT, OutputT> {\n    private class Context extends DoFn<InputT, OutputT>.StartBundleContext {\n      Context() {\n        doFn.super();","sourceCodeStart":1555,"sourceCodeEnd":1591,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java#L1555-L1591","documentation":"Thrown by the DoFnProcessContext/OutputReceiver when an element is emitted (via OutputReceiver.output or c.outputWithTimestamp) with a timestamp outside the allowed bounds: earlier than the current element's timestamp minus getAllowedTimestampSkew, or later than TIMESTAMP_MAX_VALUE. This enforces Beam's timestamp skew invariant for DoFn outputs in the Fn API harness.","triggerScenarios":"Calling c.output(value, timestamp) or c.outputWithTimestamp(tag, value, timestamp) where timestamp.isBefore(currentElement.getTimestamp().minus(allowedSkew)) || timestamp.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE).","commonSituations":"Re-timestamping outputs far into the past without declaring a skew; emitting timestamps computed from clock values before the element time; test data with Instant.MAX causing overflow past TIMESTAMP_MAX_VALUE; runners that do not permit arbitrary timestamps (BEAM-29637 semantics).","solutions":["Override @GetAllowedTimestampSkew on the DoFn to return a Duration large enough to cover your output timestamps.","Emit with a timestamp >= element timestamp minus allowed skew; clamp the computed timestamp before calling output.","Clamp timestamps to BoundedWindow.TIMESTAMP_MAX_VALUE before emitting.","If the element timestamp itself is wrong, fix upstream timestamp assignment (e.g. watermark/DoFn source) rather than adjusting skew."],"exampleFix":"// before\ncontext.outputWithTimestamp(out, value, eventTime.minus(Duration.standardDays(2)));\n\n// after: declare the skew\n@GetAllowedTimestampSkew\npublic Duration getAllowedTimestampSkew() { return Duration.standardDays(3); }\ncontext.outputWithTimestamp(out, value, eventTime.minus(Duration.standardDays(2)));","handlingStrategy":"validation","validationCode":"Instant lowerBound = currentElement.getTimestamp().minus(doFn.getAllowedTimestampSkew());\nif (ts.isBefore(lowerBound)) ts = lowerBound;\nif (ts.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE)) ts = BoundedWindow.TIMESTAMP_MAX_VALUE;","typeGuard":null,"tryCatchPattern":"try {\n  c.outputWithTimestamp(out, value, ts);\n} catch (IllegalArgumentException e) {\n  // fallback: emit at input timestamp\n  c.output(value);\n}","preventionTips":["Override getAllowedTimestampSkew when re-timestamping backwards","Clamp output timestamps before emission","Test DoFns that shift timestamps with TestPipeline"],"tags":["beam","timestamp","output","allowed-timestamp-skew"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}