apache/beam · error · IllegalStateException
Timers are unsupported because the ProcessBundleRequest %s d
Error message
Timers are unsupported because the ProcessBundleRequest %s does not provide a timer ApiServiceDescriptor.
What it means
The pipeline contains timers, so the SDK harness tries to register an outgoing timers endpoint for the timer family. But the ProcessBundleRequest sent by the runner did not include a timer ApiServiceDescriptor, meaning the runner provided no gRPC endpoint to deliver timers to. BeamFnLoggingClient's sibling ProcessBundleHandler throws IllegalStateException in addOutgoingTimersEndpoint.
Source
Thrown at sdks/java/harness/src/main/java/org/apache/beam/fn/harness/control/ProcessBundleHandler.java:392
org.apache.beam.sdk.coders.Coder<T> coder) {
BeamFnDataOutboundAggregator aggregator =
outboundAggregatorMap.computeIfAbsent(
apiServiceDescriptor,
asd ->
new BeamFnDataOutboundAggregator(
options,
runnerCapabilities.contains(
BeamUrns.getUrn(
StandardRunnerProtocols.Enum
.CONTROL_RESPONSE_ELEMENTS_EMBEDDING))));
return aggregator.registerOutputDataLocation(pTransformId, coder);
}
@Override
public <T> FnDataReceiver<Timer<T>> addOutgoingTimersEndpoint(
String timerFamilyId, org.apache.beam.sdk.coders.Coder<Timer<T>> coder) {
if (!processBundleDescriptor.hasTimerApiServiceDescriptor()) {
throw new IllegalStateException(
String.format(
"Timers are unsupported because the ProcessBundleRequest %s does not"
+ " provide a timer ApiServiceDescriptor.",
processBundleInstructionId.get()));
}
BeamFnDataOutboundAggregator aggregator =
outboundAggregatorMap.computeIfAbsent(
processBundleDescriptor.getTimerApiServiceDescriptor(),
asd ->
new BeamFnDataOutboundAggregator(
options,
runnerCapabilities.contains(
BeamUrns.getUrn(
StandardRunnerProtocols.Enum
.CONTROL_RESPONSE_ELEMENTS_EMBEDDING))));
return aggregator.registerOutputTimersLocation(
pTransformId, timerFamilyId, coder);
}View on GitHub (pinned to 12126d8942)
Solutions
- Use a runner/backend that supports timers over the Fn API and ensure it sends the timer ApiServiceDescriptor.
- Upgrade runner and SDK harness to matching versions where timers are supported.
- Remove @OnTimer usage (or the whole stateful DoFn) if targeting a backend without timer support.
- Inspect ProcessBundleRequest/instruction logs to confirm timerApiServiceDescriptor is populated by the runner.
Example fix
// before // runner config without timer support running stateful DoFn // after // upgrade runner, e.g. use a Flink/Beam version that sends timerApiServiceDescriptor, or drop @OnTimer
Defensive patterns
Strategy: validation
Validate before calling
// before submitting: if (doFnUsesTimers && !runnerSupportsTimers(backendVersion)) throw new IllegalArgumentException("Backend lacks timer support"); Try / catch
try { startBundleWithTimers(); } catch (IllegalStateException e) { if (e.getMessage().contains("does not provide a timer ApiServiceDescriptor")) { /* fail fast / switch runner */ } throw e; } Prevention
- Confirm the runner/backend supports Fn API timers before using @OnTimer
- Keep runner and SDK harness versions in lockstep
- Remove timer usage for unsupported backends
When it happens
Trigger: A DoFn with @OnTimer / state timers runs in a bundle whose ProcessBundleRequest lacks timerApiServiceDescriptor — typically a runner/portability backend that does not support timers, or a misconfigured job where the instruction's API service descriptors omit timers.
Common situations: Running a stateful DoFn on a portability runner/backend without timer support (older Flink/Spark portable versions, custom runners, direct harness misconfig); runner/harness version mismatch where the runner doesn't send the timer endpoint.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Cannot access timerId as parameter outside of @OnTimer metho
- Not expected to access TimeDomain from @ProcessElement
- %s is splittable and uses timers, but these are not compatib
- %s is splittable and uses timer family, but these are not co
- Unable to construct @OnTimer invoker for ${className}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/b58c43ed09f77a72.
Report an issue: GitHub.