apache/cassandra · error · ConfigurationException

Invalid value for option

Error message

Invalid value %s for option '%s'

What it means

HybridSpeculativeRetryPolicy.fromString parses MIN(x, y)/MAX(x, y) forms of SPECULATIVE_RETRY. It throws ConfigurationException 'Invalid value %s for option 'speculative_retry'' when either inner value fails to parse, and additionally when both arguments are of the same kind (e.g. MIN(50ms, 80ms) or MIN(99PERCENTILE, 95PERCENTILE)).

Solutions

  1. Use one fixed (ms) and one percentile argument, e.g. SPECULATIVE_RETRY = 'MIN(50ms, 99PERCENTILE)'
  2. Match the exact casing/spacing the pattern accepts: MIN(...)/MAX(...) with valid inner policies
  3. Simplify to a single fixed '50ms' or percentile '99PERCENTILE' policy if a hybrid isn't needed
  4. Check server logs/docs for the supported grammar of speculative_retry in your version

Example fix

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

Strategy: validation

Validate before calling

// validate hybrid speculative_retry syntax and argument kinds
Pattern p = Pattern.compile("(MIN|MAX)\\((\\d+ms|\\d+PERCENTILE),\\s*(\\d+ms|\\d+PERCENTILE)\\)");
Matcher m = p.matcher(value);
if (!m.matches() || m.group(2).equals(m.group(3))) throw new IllegalArgumentException("need one ms + one PERCENTILE arg");

Try / catch

try { session.execute(alter); } catch (com.datastax.driver.core.exceptions.InvalidQueryException e) { if (e.getMessage().contains("speculative_retry")) sanitizeAndRetry(); else throw e; }

Prevention

When it happens

Trigger: SPECULATIVE_RETRY = 'MIN(50ms, 80ms)' (both fixed), 'MAX(99PERCENTILE, 95PERCENTILE)' (both percentile), or unparseable inner values like 'MIN(50ms, bogus)'.

Common situations: Assuming same-type arguments are allowed, mixing up syntax from other databases, or typos inside the parentheses.

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/cf26837614006ab5. Report an issue: GitHub.

Appendix: source

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

    static HybridSpeculativeRetryPolicy fromString(String str)
    {
        Matcher matcher = PATTERN.matcher(str);

        if (!matcher.matches())
            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)
    {

View on GitHub (pinned to 88fd0f6a0e)