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

  1. Remove the maxmax ceiling when the max bound is a constant
  2. Use a dynamic max wait (e.g. latency-based) if an absolute ceiling is needed
  3. 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

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


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)