apache/cassandra · error · java.lang.IllegalArgumentException
Invalid duration: value must be non-negative
Error message
Invalid duration: value must be non-negative
What it means
The numeric validateQuantity overload rejects negative quantities for duration specs. Durations in Cassandra config must be non-negative; -1 is not a valid disable marker here. Thrown as IllegalArgumentException.
Source
Thrown at src/java/org/apache/cassandra/config/DurationSpec.java:120
private static String acceptedUnits(TimeUnit minUnit)
{
TimeUnit[] units = TimeUnit.values();
return Arrays.toString(Arrays.copyOfRange(units, minUnit.ordinal(), units.length));
}
private static void validateQuantity(String value, long quantity, TimeUnit sourceUnit, TimeUnit minUnit, long max)
{
// no need to validate for negatives as they are not allowed at first place from the regex
if (minUnit.convert(quantity, sourceUnit) >= max)
throw new IllegalArgumentException("Invalid duration: " + value + ". It shouldn't be more than " +
(max - 1) + " in " + toLowerCaseLocalized(minUnit.name()));
}
private static void validateQuantity(long quantity, TimeUnit sourceUnit, TimeUnit minUnit, long max)
{
if (quantity < 0)
throw new IllegalArgumentException("Invalid duration: value must be non-negative");
if (minUnit.convert(quantity, sourceUnit) >= max)
throw new IllegalArgumentException(String.format("Invalid duration: %d %s. It shouldn't be more than %d in %s",
quantity, toLowerCaseLocalized(sourceUnit.name()),
max - 1, toLowerCaseLocalized(minUnit.name())));
}
// get vs no-get prefix is not consistent in the code base, but for classes involved with config parsing, it is
// imporant to be explicit about get/set as this changes how parsing is done; this class is a data-type, so is
// not nested, having get/set can confuse parsing thinking this is a nested type
public long quantity()
{
return quantity;
}
public TimeUnit unit()
{
return unit;View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Replace negative values with 0 (or the property's documented disable value)
- Clamp computed durations with Math.max(0, value) before assignment
- Use the property's documented mechanism for disabling instead of a negative duration
Example fix
// before spec.set(retryDelaySeconds); // after spec.set(Math.max(0, retryDelaySeconds));
Defensive patterns
Strategy: validation
Validate before calling
static long requireNonNegative(long v) {
if (v < 0) throw new IllegalArgumentException("Duration must be non-negative");
return v;
} Try / catch
try {
spec.set(value);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("non-negative"))
logger.error("Negative duration passed: {}", value);
} Prevention
- Never use -1 as a duration; use documented disable values
- Clamp computed durations with Math.max(0, x)
- Fuzz/CI test programmatic config builders for sign errors
When it happens
Trigger: Calling a DurationSpec subclass constructor or setter with a negative long, e.g. new SomeDurationSpec(-1, TimeUnit.SECONDS) or programmatically assigning a negative value via a config mutation API.
Common situations: Using -1 to mean 'infinite/disabled' in code that programmatically builds config; sign errors when computing durations dynamically.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid duration: %s Accepted units:%s where case matters an
- Invalid data rate: value must be non-negative
- Invalid data storage: %s Accepted units:%s
- Invalid value of auto_snapshot_ttl: ${conf.auto_snapshot_ttl
- Invalid value of entire_sstable_stream_throughput_outbound:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ff3d1b5dbf2f0911.
Report an issue: GitHub.