apache/druid · error · IllegalArgumentException
maxAttempts must be positive (limited) or negative…
Error message
maxAttempts must be positive (limited) or negative (unlimited); cannot be zero.
What it means
StandardRetryPolicy encodes limited retries as a positive maxAttempts and unlimited retries as a negative value. Zero is semantically meaningless (would mean never try at all), so the constructor rejects it with IllegalArgumentException.
Solutions
- Set maxAttempts to at least 1 for a finite number of attempts (1 = no retries).
- Use a negative value such as -1 to express unlimited retries.
- Clamp or default config-derived values: if maxAttempts == 0, use the builder default.
Example fix
// before StandardRetryPolicy policy = StandardRetryPolicy.builder().maxAttempts(0).build(); // after StandardRetryPolicy policy = StandardRetryPolicy.builder().maxAttempts(1).build(); // no retries
Defensive patterns
Strategy: validation
Validate before calling
if (maxAttempts == 0) {
maxAttempts = 1; // no retries, one attempt
} Prevention
- Treat 0 as 'one attempt' in config mapping; use negative values for unlimited.
- Document retry semantics where maxAttempts is configured.
When it happens
Trigger: Building a StandardRetryPolicy via the constructor or Builder with maxAttempts = 0, typically from a config value that defaulted to 0 or was computed by subtraction.
Common situations: Users setting "maxAttempts: 0" in config expecting retries to be disabled (should use negative for unlimited or 1 for no retries), or code computing maxRetries - 1 yielding 0.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- A-Not-B requires at least 1 sketch
- BloomKFilters are not compatible for merging. this
- Bucket index out of range (0, )
- Caching is not supported. Check `isCacheable` before…
- Cannot add files of the same name, already have
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/20e68e8ae1dbeca7.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/rpc/StandardRetryPolicy.java:75
private final boolean retryNotAvailable;
private final boolean retryLoggable;
private StandardRetryPolicy(
long maxAttempts,
long minWaitMillis,
long maxWaitMillis,
boolean retryNotAvailable,
boolean retryLoggable
)
{
this.maxAttempts = maxAttempts;
this.minWaitMillis = minWaitMillis;
this.maxWaitMillis = maxWaitMillis;
this.retryNotAvailable = retryNotAvailable;
this.retryLoggable = retryLoggable;
if (maxAttempts == 0) {
throw new IAE("maxAttempts must be positive (limited) or negative (unlimited); cannot be zero.");
}
}
public static Builder builder()
{
return new Builder();
}
/**
* Standard unlimited retry policy. Never stops retrying as long as errors remain retryable.
* See {@link ServiceClient} documentation for details on what errors are retryable.
*/
public static StandardRetryPolicy unlimited()
{
return DEFAULT_UNLIMITED_POLICY;
}
/**View on GitHub (pinned to 9b90983fd2)