apache/cassandra · error · IllegalArgumentException
Invalid specification
Error message
Invalid specification: '${spec}'; does not match ${PARSE} What it means
After stripping trailing key=value modifiers, the remaining wait specification must fully match the RetryStrategy.PARSE regex (the '[min..]max[;bounds]' grammar with optional absolute min/max clamps). If it does not, RetryStrategy.parse() throws an IllegalArgumentException showing the spec and the expected pattern.
Solutions
- Match the documented format: <min>..<max> with valid durations, e.g. "100ms..1s"
- Check units are accepted by TimeoutStrategy.parseWait (us, ms, s, m)
- Ensure the range is ordered min <= max if both bounds are given
- Print the PARSE pattern included in the message and compare character by character with your spec
Example fix
// before
RetryStrategy.parse("100 MSECONDS to 1s", latencies);
// after
RetryStrategy.parse("100ms..1s", latencies); Defensive patterns
Strategy: try-catch
Validate before calling
private static final Pattern SIMPLE_SPEC = Pattern.compile("(\\d+(us|ms|s|m))(\\.\\.(\\d+(us|ms|s|m)))?");
static boolean looksLikeValidWaitSpec(String spec) {
String waitPart = spec.split(",")[0];
return SIMPLE_SPEC.matcher(waitPart).matches();
} Try / catch
try {
RetryStrategy strategy = RetryStrategy.parse(spec, latencies);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Invalid specification:")) {
throw new ConfigurationException("Retry spec '" + spec + "' invalid; expected e.g. '100ms..1s[,key=value]'");
}
throw e;
} Prevention
- Follow the canonical form: [<min>..]<max>[,modifiers]
- Use accepted duration units (us, ms, s, m) without spaces
- Validate all retry specs in a startup config-check pass
- Quote specs in YAML so whitespace does not corrupt them
When it happens
Trigger: RetryStrategy.parse(spec, latencies) where the wait part is malformed: empty string, "100ms.." without a max, misspelled units ("100 MSECONDS"), reversed range ("1s..100ms"), or leftover garbage after the modifier parser stops consuming the string.
Common situations: Hand-edited cassandra.yaml retry specs; specs copied between versions where the accepted grammar changed; trailing junk left after modifier parsing truncated the spec.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- does not match
- Invalid modifier specification: unrecognised property
- Commit log position must be given as
- could not parse update query
- denylist_max_keys_per_table must be a positive integer.
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0c62b749c9c549ca.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/RetryStrategy.java:305
retries = Integer.parseInt(value);
if (retries < 0)
throw new IllegalArgumentException("Must permit at least one attempt (attempts=" + value + " supplied)");
break;
case "rnd":
if (randomizer != null)
throw new IllegalArgumentException("Randomizer already specified, cannot re-specify: " + value);
randomizer = parseWaitRandomizer(value);
break;
}
end = next;
}
if (end != spec.length())
spec = spec.substring(0, end);
}
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);View on GitHub (pinned to 88fd0f6a0e)