apache/cassandra · error · IllegalArgumentException

Unrecognised attempt modifier

Error message

Unrecognised attempt modifier: {modkind}

What it means

IllegalArgumentException from TimeoutStrategy.parseLatencyModifier when parsing a latency modifier spec: the modifier kind (modkind) is not a recognized attempt-based modifier. This is a guard over user-supplied configuration strings for simulated/adjusted timeouts; only known modifier syntaxes (e.g. a leading '*' constant factor) are accepted.

Solutions

  1. Use '*' for multiplicative attempt modifiers (e.g. '*1.5').
  2. Use '^' for exponential attempt modifiers (e.g. '^2').
  3. Remove any other prefix characters from the modifier segment.

Example fix

// before
String spec = "exponential(100ms)+2"; // invalid modifier
// after
String spec = "exponential(100ms)*2";
Defensive patterns

Strategy: validation

Validate before calling

if (modkind != null && !modkind.startsWith("*") && !modkind.startsWith("^")) throw new IllegalArgumentException("modifier must start with * or ^: " + modkind);

Try / catch

try { TimeoutStrategy.parse(spec, latencies); }
catch (IllegalArgumentException e) { if (e.getMessage().contains("Unrecognised attempt modifier")) { /* fix to *N or ^N */ } throw e; }

Prevention

When it happens

Trigger: A timeout spec whose modifier starts with a character other than '*' or '^' after the latency expression, e.g. '+2' or '%2'.

Common situations: Typo like '*x2' or 'x2' in a configured timeout strategy string; copy-paste from docs of other systems.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/service/TimeoutStrategy.java:331

    private static @Nullable LatencyModifier parseLatencyModifier(String spec, Matcher m, LatencyModifierFactory modifiers)
    {
        String mod = m.group("mod");
        String modkind = m.group("modkind");
        double modifier = 1.0;
        if (mod != null) modifier = Double.parseDouble(mod);
        else if (modkind == null) return null;
        else if (!modkind.startsWith("*"))
            throw new IllegalArgumentException("Invalid latency modifier specification: " + spec + ". Expect constant factor as base for exponent.");

        if (modkind == null)
            return modifiers.multiply(modifier);

        if (modkind.startsWith("*"))
            return modifiers.multiplyByAttempts(modifier);
        else if (modkind.startsWith("^"))
            return modifiers.multiplyByAttemptsExp(modifier);
        else
            throw new IllegalArgumentException("Unrecognised attempt modifier: " + modkind);
    }

    static long saturatedCast(double v)
    {
        if (v > Long.MAX_VALUE)
            return Long.MAX_VALUE;
        return (long) v;
    }

    public static TimeoutStrategy parse(String input, LatencySourceFactory latencies)
    {
        Matcher m = PARSE.matcher(input);
        if (!m.matches())
            throw new IllegalArgumentException("Invalid specification: '" + input + "'; does not match " + PARSE);
        long min = parseInMicros(m.group("min"), 0);
        long max = parseInMicros(m.group("max"), Long.MAX_VALUE);
        Wait wait = TimeoutStrategy.parseWait(m.group("wait"), latencies);
        return new TimeoutStrategy(wait, min, max);

View on GitHub (pinned to 88fd0f6a0e)