apache/cassandra · error · ConfigurationException

Invalid value for option ' ': MIN()/MAX() arguments should…

Error message

Invalid value %s for option '%s': MIN()/MAX() arguments should be of different types, but both are of type %s

What it means

Thrown by HybridSpeculativeRetryPolicy.fromString when parsing a MIN()/MAX() speculative_retry value whose two arguments are the same kind (e.g. MIN(50ms, 60ms) — both fixed, or MIN(50p, 99p) — both percentile). MIN/MAX hybrids require one fixed and one percentile argument so the policy can pick between a time bound and a percentile bound.

Solutions

  1. Change the MIN()/MAX() arguments so one is a fixed time (e.g. 50ms) and the other a percentile (e.g. 99p)
  2. If only one bound is needed, drop the hybrid entirely and set speculative_retry to the plain value (e.g. '50ms' or '99p')
  3. Use 'NONE' to disable speculative retries and re-evaluate the intended tuning

Example fix

// before
ALTER TABLE ks.tbl WITH speculative_retry = 'MIN(50ms, 95ms)';
// after
ALTER TABLE ks.tbl WITH speculative_retry = 'MIN(50ms, 95p)';
Defensive patterns

Strategy: validation

Validate before calling

function isValidSpeculativeRetry(v) {
  const m = /^(MIN|MAX)\(([^,]+),([^,]+)\)$/i.exec(v.trim());
  if (!m) return false;
  const kind = s => /p$|percentile$/i.test(s.trim()) ? 'percentile' : 'fixed';
  return kind(m[2]) !== kind(m[3]);
}
if (!isValidSpeculativeRetry('MIN(50ms, 95p)')) throw new Error('MIN/MAX needs one fixed and one percentile arg');

Prevention

When it happens

Trigger: Setting speculative_retry to MIN(x,y) or MAX(x,y) via CREATE/ALTER TABLE or TableParams where both x and y parse to the same kind: both milliseconds/fixed values or both percentile values (e.g. 'MIN(10ms, 99p)' is valid but 'MIN(10ms, 20ms)' is not).

Common situations: Copy-pasting speculative_retry settings from old configs or docs; misunderstanding that MIN/MAX compare one time bound and one percentile; typos like 'MIN(50p, 99PERCENTILE)' where both parse as percentiles.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/4ef8091c1e7df406. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/service/reads/HybridSpeculativeRetryPolicy.java:125

            throw new IllegalArgumentException();

        String val1 = matcher.group("val1");
        String val2 = matcher.group("val2");

        SpeculativeRetryPolicy value1, value2;
        try
        {
            value1 = SpeculativeRetryPolicy.fromString(val1);
            value2 = SpeculativeRetryPolicy.fromString(val2);
        }
        catch (ConfigurationException e)
        {
            throw new ConfigurationException(String.format("Invalid value %s for option '%s'", str, TableParams.Option.SPECULATIVE_RETRY));
        }

        if (value1.kind() == value2.kind())
        {
            throw new ConfigurationException(String.format("Invalid value %s for option '%s': MIN()/MAX() arguments " +
                                                           "should be of different types, but both are of type %s",
                                                           str, TableParams.Option.SPECULATIVE_RETRY, value1.kind()));
        }

        SpeculativeRetryPolicy policy1 = value1 instanceof PercentileSpeculativeRetryPolicy ? value1 : value2;
        SpeculativeRetryPolicy policy2 = value1 instanceof FixedSpeculativeRetryPolicy ? value1 : value2;

        Function function = Function.valueOf(toUpperCaseLocalized(matcher.group("fun")));
        return new HybridSpeculativeRetryPolicy((PercentileSpeculativeRetryPolicy) policy1, (FixedSpeculativeRetryPolicy) policy2, function);
    }

    static boolean stringMatches(String str)
    {
        return PATTERN.matcher(str).matches();
    }
}

View on GitHub (pinned to 88fd0f6a0e)