apache/cassandra · error · IllegalArgumentException
Invalid to specify an absolute max(min) constant when the…
Error message
Invalid to specify an absolute max(min) constant when the min bound is itself a constant: '${original}' What it means
The maxmin bound caps how far the effective min wait may rise (e.g. as latency-derived mins grow). When the min bound is a Constant wait its value never varies, so capping it with maxmin is contradictory and RetryStrategy.parse() throws an IllegalArgumentException naming the original spec.
Solutions
- Remove the maxmin bound when the min bound is a constant
- Replace the constant min with a dynamic (e.g. percentile-derived) min if a cap is meaningful
- Leave maxmin at its default (unspecified) so the validation passes
Example fix
// before
RetryStrategy.parse("500ms;maxmin=300ms..1s", latencies); // constant min with maxmin cap
// after
RetryStrategy.parse("500ms..1s", latencies); // ranged min, no redundant cap Defensive patterns
Strategy: validation
Validate before calling
static void validateNoMaxminWithConstantMin(String spec, boolean minIsConstant, boolean hasMaxminCap) {
if (minIsConstant && hasMaxminCap)
throw new IllegalArgumentException("maxmin cap meaningless with constant min: " + spec);
} Try / catch
try {
RetryStrategy strategy = RetryStrategy.parse(spec, latencies);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("absolute max(min) constant")) {
throw new ConfigurationException("Remove the maxmin cap for constant min in: " + spec);
}
throw e;
} Prevention
- Use maxmin caps only when the min wait varies (dynamic bounds)
- Keep spec generation type-aware: clamps only for percentile/latency bounds
- Test generated specs against RetryStrategy.parse in unit tests
When it happens
Trigger: A spec whose min component parses to Wait.Constant while the 'maxmin' clamp (absolute cap on min, default Long.MAX_VALUE) is specified to a finite value.
Common situations: Copy-pasted clamp syntax from latency/percentile-based specs onto constant waits; template-generated specs that always emit maxmin bounds regardless of min type.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Invalid to specify an absolute maximum constant when the…
- Invalid to specify an absolute minimum constant when the…
- Invalid to specify randomiser when no range specified
- Randomizer already specified, cannot re-specify
- Cannot reset state and replay from a save point; must…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/9e97f6eb08fb90e8.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/RetryStrategy.java:318
spec = spec.substring(0, end);
}
Matcher m = PARSE.matcher(spec);
if (!m.matches())
throw new IllegalArgumentException("Invalid specification: '" + spec + "'; does not match " + PARSE);
long minMin = parseInMicros(m.group("minmin"), 0);
long maxMax = parseInMicros(m.group("maxmax"), Long.MAX_VALUE);
Wait max = TimeoutStrategy.parseWait(m.group("max"), latencies);
String minSpec = m.group("min");
Wait min = minSpec == null ? null : TimeoutStrategy.parseWait(minSpec, latencies);
if (min == null && randomizer != null)
throw new IllegalArgumentException("Invalid to specify randomiser when no range specified: '" + original + '\'');
if (min instanceof Wait.Constant && minMin != 0)
throw new IllegalArgumentException("Invalid to specify an absolute minimum constant when the min bound is itself a constant: '" + original + '\'');
long maxMin = parseInMicros(m.group("maxmin"), Long.MAX_VALUE);
if (min instanceof Wait.Constant && maxMin != Long.MAX_VALUE)
throw new IllegalArgumentException("Invalid to specify an absolute max(min) constant when the min bound is itself a constant: '" + original + '\'');
if (max instanceof Wait.Constant && maxMax != Long.MAX_VALUE)
throw new IllegalArgumentException("Invalid to specify an absolute maximum constant when the max bound is itself a constant: '" + original + '\'');
if (randomizer == null)
randomizer = randomizers.uniform();
return new RetryStrategy(randomizer, minMin, min, maxMin, max, maxMax, retries);
}
@VisibleForTesting
protected static WaitRandomizer parseWaitRandomizer(String input)
{
Matcher m = RANDOMIZER.matcher(input);
if (!m.matches())
throw new IllegalArgumentException(input + " does not match" + RANDOMIZER);
String exp;
exp = m.group("exp");
if (exp != null)
return randomizers.exponential(Double.parseDouble(exp));View on GitHub (pinned to 88fd0f6a0e)