apache/beam · error · IllegalArgumentException
Unknown or unsupported time domain
Error message
Unknown or unsupported time domain %s
What it means
Thrown by FnApiDoFnRunner when handling a timer firing whose time domain is not one of the supported domains (EVENT_TIME, PROCESSING_TIME). The Java Fn API harness only implements timer callbacks for these domains, so any other domain value reaching the switch's default branch is rejected with an IllegalArgumentException.
Solutions
- Check which time domain the DoFn/Timer was registered with and use only EVENT_TIME or PROCESSING_TIME.
- Align Beam SDK versions on both runner and SDK sides so the timer domain enum is understood consistently.
- If you control the runner side, add a case for the new domain in FnApiDoFnRunner's switch instead of falling through to default.
- Inspect the serialized timer payload sent over the Fn API to confirm the timeDomain field isn't corrupted or mis-encoded.
Example fix
// before (DoFn using an unsupported domain path)
Timer.timer(domain);
// after: only use supported domains
Timer.eventTime("myTimer"); // or Timer.processingTime("myTimer") Defensive patterns
Strategy: try-catch
Validate before calling
if (!timeDomain.equals(TimeDomain.EVENT_TIME) && !timeDomain.equals(TimeDomain.PROCESSING_TIME)) {
throw new IllegalArgumentException("Unsupported time domain: " + timeDomain);
} Type guard
boolean isSupported(TimeDomain d) { return d == TimeDomain.EVENT_TIME || d == TimeDomain.PROCESSING_TIME; } Try / catch
try {
emitTimerCallback(timeDomain);
} catch (IllegalArgumentException e) {
logger.error("Timer domain rejected: {}", timeDomain, e);
} Prevention
- Only register EVENT_TIME or PROCESSING_TIME timers in DoFns
- Keep runner and SDK Beam versions aligned
- Add a unit test covering every time domain your timers use
When it happens
Trigger: A timer registered or delivered via the Beam Fn API with a timeDomain other than EVENT_TIME or PROCESSING_TIME reaches the runner's timer-firing dispatch switch (default case at FnApiDoFnRunner.java:1345).
Common situations: A runner or SDK adds a new time domain (e.g. WATERMARK/synchronized processing time variants) while the Java Fn API harness has not been updated to handle it; cross-language pipelines where one SDK emits a timer domain the Java harness doesn't know; a wire/protocol mismatch between older and newer Beam versions.
Related errors
- Attempting to call and() on a CoGbkResult apparently not…
- Can't convert 'null' to non-nullable field
- Cannot merge schemas with different numbers of fields…
- Cannot output timer with output timestamp
- Duplicate timer family ID
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b6ac3ae0e3da11df.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/harness/src/main/java/org/apache/beam/fn/harness/FnApiDoFnRunner.java:1345
this.timerIdOrFamily = timerIdOrFamily;
this.userKey = userKey;
this.dynamicTimerTag = dynamicTimerTag;
this.elementTimestampOrTimerHoldTimestamp = elementTimestampOrTimerHoldTimestamp;
this.boundedWindow = boundedWindow;
this.paneInfo = paneInfo;
this.noOutputTimestamp = false;
this.timeDomain = timeDomain;
switch (timeDomain) {
case EVENT_TIME:
fireTimestamp = elementTimestampOrTimerFireTimestamp;
break;
case PROCESSING_TIME:
// TODO: This should use an injected clock when using TestStream.
fireTimestamp = new Instant(DateTimeUtils.currentTimeMillis());
break;
default:
throw new IllegalArgumentException(
String.format("Unknown or unsupported time domain %s", timeDomain));
}
}
@Override
public void set(Instant absoluteTime) {
checkNotNull(timerBundleTracker);
// Ensures that the target time is reasonable. For event time timers this means that the time
// should be prior to window GC time.
if (TimeDomain.EVENT_TIME.equals(timeDomain)) {
Instant windowExpiry = LateDataUtils.garbageCollectionTime(currentWindow, allowedLateness);
checkArgument(
!absoluteTime.isAfter(windowExpiry),
"Attempted to set event time timer for %s but that is after"
+ " the expiration of window %s",
absoluteTime,
windowExpiry);
}View on GitHub (pinned to 12126d8942)