apache/beam · error · IllegalArgumentException
Cannot output with timestamp
Error message
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.
What it means
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.
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.
Example fix
// before
context.outputWithTimestamp(out, value, eventTime.minus(Duration.standardDays(2)));
// after: declare the skew
@GetAllowedTimestampSkew
public Duration getAllowedTimestampSkew() { return Duration.standardDays(3); }
context.outputWithTimestamp(out, value, eventTime.minus(Duration.standardDays(2))); Defensive patterns
Strategy: validation
Validate before calling
Instant lowerBound = currentElement.getTimestamp().minus(doFn.getAllowedTimestampSkew()); if (ts.isBefore(lowerBound)) ts = lowerBound; if (ts.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE)) ts = BoundedWindow.TIMESTAMP_MAX_VALUE;
Try / catch
try {
c.outputWithTimestamp(out, value, ts);
} catch (IllegalArgumentException e) {
// fallback: emit at input timestamp
c.output(value);
} Prevention
- Override getAllowedTimestampSkew when re-timestamping backwards
- Clamp output timestamps before emission
- Test DoFns that shift timestamps with TestPipeline
When it happens
Trigger: Calling c.output(value, timestamp) or c.outputWithTimestamp(tag, value, timestamp) where timestamp.isBefore(currentElement.getTimestamp().minus(allowedSkew)) || timestamp.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE).
Common situations: 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).
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Cannot output timer with output timestamp
- BigQuery data contained value
- Converting BigQuery type to Beam type is unsupported
- SolaceIO.Write.UnboundedSolaceWriter.Context: Timestamp is…
- Timestamp logical type precision not supported
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/959d05d91b9276d1.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java:1573
boundedWindow,
elementTimestampOrTimerHoldTimestamp,
elementTimestampOrTimerFireTimestamp,
paneInfo,
timeDomain);
}
}
@SuppressWarnings("deprecation") // Allowed Skew is deprecated for users, but must be respected
private void checkTimestamp(Instant timestamp) {
Instant lowerBound;
try {
lowerBound = currentElement.getTimestamp().minus(doFn.getAllowedTimestampSkew());
} catch (ArithmeticException e) {
lowerBound = BoundedWindow.TIMESTAMP_MIN_VALUE;
}
if (timestamp.isBefore(lowerBound) || timestamp.isAfter(BoundedWindow.TIMESTAMP_MAX_VALUE)) {
throw new IllegalArgumentException(
String.format(
"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.",
timestamp,
currentElement.getTimestamp(),
doFn.getAllowedTimestampSkew().getMillis() >= Integer.MAX_VALUE
? doFn.getAllowedTimestampSkew()
: PeriodFormat.getDefault().print(doFn.getAllowedTimestampSkew().toPeriod()),
BoundedWindow.TIMESTAMP_MAX_VALUE));
}
}
private class StartBundleArgumentProvider extends BaseArgumentProvider<InputT, OutputT> {
private class Context extends DoFn<InputT, OutputT>.StartBundleContext {
Context() {
doFn.super();View on GitHub (pinned to 12126d8942)