apache/cassandra · error · IllegalArgumentException
Must permit at least one attempt
Error message
Must permit at least one attempt (attempts=${value} supplied) What it means
When parsing an 'attempts=<n>' modifier, RetryStrategy.parse() rejects negative values because at least one attempt must be permitted (the initial attempt counts). An IllegalArgumentException naming the supplied value is thrown.
Solutions
- Set attempts to a non-negative integer (0 or more)
- To allow unlimited attempts, omit the modifier rather than using a negative value
- Use the 'retries=' modifier instead if you want to count retries rather than total attempts
Example fix
// before
RetryStrategy.parse("100ms,attempts=-1", latencies);
// after
RetryStrategy.parse("100ms", latencies); // default permits effectively unlimited attempts Defensive patterns
Strategy: validation
Validate before calling
static int validateAttempts(String value) {
int attempts = Integer.parseInt(value.trim());
if (attempts < 0) throw new IllegalArgumentException("attempts must be >= 0, got " + value);
return attempts;
} Try / catch
try {
RetryStrategy strategy = RetryStrategy.parse(spec, latencies);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Must permit at least one attempt")) {
LOG.warn("Invalid attempts in spec '{}', using default", spec);
return RetryStrategy.parse("100ms", latencies);
}
throw e;
} Prevention
- Remember attempts counts total tries, so it must be >= 0
- Omit the modifier for effectively unlimited attempts instead of -1
- Clamp generated values with Math.max(0, attempts) before building the spec
When it happens
Trigger: RetryStrategy.parse(spec, latencies) where spec ends with ',attempts=-2' or any negative integer. The value must be an int >= 0.
Common situations: Using attempts=-1 intending 'infinite attempts' (omit the modifier instead, since default retries is Integer.MAX_VALUE); automated config generators emitting negative placeholders.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- retries must be non-negative
- Commit log position must be given as
- could not parse update query
- does not end in unit
- does not match
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/22f54a0e19d6c48c.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/RetryStrategy.java:289
while ((next = spec.lastIndexOf(',', end - 1)) >= 0)
{
int mid = spec.indexOf('=', next + 1);
if (mid <= next || mid >= end)
throw new IllegalArgumentException("Invalid modifier specification: '" + spec.substring(next, end) + "'; expecting '=' for value assignment");
String key = spec.substring(next + 1, mid).trim();
String value = spec.substring(mid + 1, end).trim();
switch (key)
{
default: throw new IllegalArgumentException("Invalid modifier specification: unrecognised property '" + key + '\'');
case "retries":
retries = Integer.parseInt(value);
if (retries < 0)
throw new IllegalArgumentException("retries must be non-negative (retries=" + value + " supplied)");
break;
case "attempts":
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);View on GitHub (pinned to 88fd0f6a0e)