apache/cassandra · error · IllegalArgumentException
Invalid to specify an absolute maximum constant when the…
Error message
Invalid to specify an absolute maximum constant when the max bound is itself a constant: '${original}' What it means
The maxmax bound is an absolute ceiling on the computed max wait. If the max bound itself is a Constant wait its value is fixed and clamping it is contradictory, so RetryStrategy.parse() throws an IllegalArgumentException naming the original spec.
Solutions
- Remove the maxmax ceiling when the max bound is a constant
- Use a dynamic max wait (e.g. latency-based) if an absolute ceiling is needed
- Leave maxmax unspecified (defaults to Long.MAX_VALUE) to satisfy validation
Example fix
// before
RetryStrategy.parse("500ms;maxmax=1s", latencies); // constant max with absolute ceiling
// after
RetryStrategy.parse("500ms", latencies); // constant max needs no ceiling Defensive patterns
Strategy: validation
Validate before calling
static void validateNoMaxmaxWithConstantMax(String spec, boolean maxIsConstant, boolean hasMaxmaxCeiling) {
if (maxIsConstant && hasMaxmaxCeiling)
throw new IllegalArgumentException("maxmax ceiling meaningless with constant max: " + spec);
} Try / catch
try {
RetryStrategy strategy = RetryStrategy.parse(spec, latencies);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("absolute maximum constant")) {
throw new ConfigurationException("Remove the maxmax ceiling for constant max in: " + spec);
}
throw e;
} Prevention
- Do not attach a maxmax ceiling when the max wait is a fixed constant
- Apply global ceilings only to latency-derived max waits
- Add a config lint step that rejects constant-plus-clamp spec combinations
When it happens
Trigger: A spec whose max component parses to Wait.Constant while a non-default 'maxmax' absolute ceiling is supplied, e.g. "500ms;maxmax=1s" where the max is a constant — the ceiling can never engage.
Common situations: Applying global clamp bounds intended for percentile-based max waits to a fixed-wait spec; combining constant bounds and absolute clamps copied from another retry policy configuration.
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 max(min) 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/92376e5de9273e2a.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/RetryStrategy.java:320
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));
exp = m.group("qexp");
if (exp != null)View on GitHub (pinned to 88fd0f6a0e)