apache/beam · error · IllegalArgumentException
throttleDelaySecs must be greater than 0
Error message
throttleDelaySecs must be greater than 0
What it means
ReactiveThrottler extends AdaptiveThrottler and adds a shared throttling signal with a fixed delay; its constructor rejects throttleDelaySecs <= 0 with an IllegalArgumentException. The delay is how long clients back off after an overloaded signal is observed, so a zero or negative delay is nonsensical. The check runs after the superclass overloadRatio validation.
Source
Thrown at sdks/java/io/components/src/main/java/org/apache/beam/sdk/io/components/throttling/ReactiveThrottler.java:59
/**
* Initializes the ReactiveThrottler.
*
* @param samplePeriodMs length of history to consider, in ms, to set throttling.
* @param sampleUpdateMs granularity of time buckets that we store data in, in ms.
* @param overloadRatio the target ratio between requests sent and successful requests.
* @param namespace the namespace to use for logging and signaling throttling is occurring.
* @param throttleDelaySecs the amount of time in seconds to wait after preemptively throttled
* requests.
*/
public ReactiveThrottler(
long samplePeriodMs,
long sampleUpdateMs,
double overloadRatio,
String namespace,
int throttleDelaySecs) {
super(samplePeriodMs, sampleUpdateMs, overloadRatio);
if (throttleDelaySecs <= 0) {
throw new IllegalArgumentException("throttleDelaySecs must be greater than 0");
}
this.throttlingSignaler = new ThrottlingSignaler(namespace);
this.throttleDelaySecs = throttleDelaySecs;
}
/**
* Stops request code from advancing while the underlying AdaptiveThrottler is signaling to
* preemptively throttle the request. Automatically handles logging the throttling and signaling
* to the SDK harness that the request is being throttled. This should be called in any context
* where a call to a remote service is being contacted prior to the call being performed.
*/
public void throttle() throws InterruptedException {
if (throttleRequest(System.currentTimeMillis())) {
LOG.debug("Delaying request for {} seconds due to previous failures", throttleDelaySecs);
Thread.sleep(throttleDelaySecs * SECONDS_TO_MILLISECONDS);
throttlingSignaler.signalThrottling(throttleDelaySecs * SECONDS_TO_MILLISECONDS);
}
}View on GitHub (pinned to 12126d8942)
Solutions
- Pass a positive throttleDelaySecs (e.g. 30 for a 30-second back off).
- Clamp or default the config value before constructing: throttleDelaySecs <= 0 ? 30 : throttleDelaySecs.
- Verify constructor argument order so the delay parameter isn't receiving another value.
Example fix
// before ReactiveThrottler t = new ReactiveThrottler(1000, 100, 1.3, "myApi", 0); // after ReactiveThrottler t = new ReactiveThrottler(1000, 100, 1.3, "myApi", 30);
Defensive patterns
Strategy: validation
Validate before calling
if (throttleDelaySecs <= 0) throw new IllegalArgumentException("throttleDelaySecs must be > 0");
ReactiveThrottler t = new ReactiveThrottler(1000, 100, 1.3, namespace, throttleDelaySecs); Try / catch
try { new ReactiveThrottler(sp, su, or, ns, delay); } catch (IllegalArgumentException e) { delay = 30; /* fall back to sane delay */ } Prevention
- Clamp config-sourced delays to a positive default (e.g. 30s).
- Document parameter order; build via a builder or named config object to avoid transposition.
- Assert configuration sanity in a startup check before pipeline launch.
When it happens
Trigger: Calling new ReactiveThrottler(samplePeriodMs, sampleUpdateMs, overloadRatio, namespace, throttleDelaySecs) with throttleDelaySecs <= 0, e.g. 0 or -1.
Common situations: Passing 0 hoping for 'no delay'; loading the value from config where it defaults to 0; accidentally swapping argument order so throttleDelaySecs receives a negative/zero value.
Related errors
- overloadRatio must be greater than 1.0
- requires an input Schema. Note that only Row or user classe
- header does not contain required %s field: %s
- Unsupported type: , consider using withCustomRecordParsing
- field was received -- type mismatch
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/82521e016c399809.
Report an issue: GitHub.