apache/beam · error · UnsupportedOperationException
Timer unsupported in
Error message
Timer unsupported in %s
What it means
Requesting a Timer object from the stub DoFnInvoker implementation throws UnsupportedOperationException. Timers require a runner-backed context, which the base class never supplies. getErrorContext() names the DoFn and call context.
Solutions
- Construct the invoker via DoFnInvokers.newInvoker/tryInvokeFor
- Only request Timer inside lifecycle methods whose signature includes the timer parameter
- Confirm the runner supports timers for this pipeline
Example fix
// before
new DoFnInvoker.BaseDoFnInvoker<T, O>(){}.timer("myTimer"); // throws
// after
DoFnInvokers.tryInvokeFor(fn).timer("myTimer"); Defensive patterns
Strategy: validation
Validate before calling
if (signature.getTimerDeclarations().containsKey(timerId)) {
ensureInvokerSupportsTimers(invoker);
} Type guard
boolean supportsTimers(DoFnInvoker<?, ?> i) {
return !(i instanceof DoFnInvoker.BaseDoFnInvoker);
} Try / catch
try {
Timer timer = invoker.timer(timerId);
} catch (UnsupportedOperationException e) {
throw new IllegalStateException("Timer unsupported for this invoker", e);
} Prevention
- Set timers via the @TimerId parameter inside lifecycle methods, not the invoker directly
- Check runner timer support before pipeline submission
- Use DoFnInvokers-built invokers in tests
When it happens
Trigger: Calling timer(timerId) on an invoker that does not override it — i.e. a placeholder invoker rather than one produced by DoFnInvokers.
Common situations: Using @TimerId with a runner lacking timer support; unit-test invokers built from the abstract base; accessing timers outside the appropriate lifecycle phase.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot access fire timestamp outside of @OnTimer method.
- Cannot access OnTimerContext outside of @OnTimer methods.
- Cannot access time domain outside of @ProcessTimer method.
- Cannot access timerId as parameter outside of @OnTimer…
- CausedByDrain unsupported in
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/1500c23fc7076c10.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java:470
throw new UnsupportedOperationException(
String.format("OnWindowExpirationContext unsupported in %s", getErrorContext()));
}
@Override
public State state(String stateId, boolean alwaysFetched) {
throw new UnsupportedOperationException(
String.format("State unsupported in %s", getErrorContext()));
}
@Override
public Timer timer(String timerId) {
throw new UnsupportedOperationException(
String.format("Timer unsupported in %s", getErrorContext()));
}
@Override
public RestrictionTracker<?, ?> restrictionTracker() {
throw new UnsupportedOperationException(
String.format("RestrictionTracker unsupported in %s", getErrorContext()));
}
@Override
public Object watermarkEstimatorState() {
throw new UnsupportedOperationException(
String.format("WatermarkEstimatorState unsupported in %s", getErrorContext()));
}
@Override
public WatermarkEstimator<?> watermarkEstimator() {
throw new UnsupportedOperationException(
String.format("WatermarkEstimator unsupported in %s", getErrorContext()));
}
@Override
public BundleFinalizer bundleFinalizer() {
throw new UnsupportedOperationException(View on GitHub (pinned to 12126d8942)