apache/cassandra · error · IllegalArgumentException
Invalid duration. The %s should be after %s
Error message
Invalid duration. The %s should be after %s
What it means
Thrown by Duration.Builder.validateOrder when duration units appear out of descending order. The CQL duration grammar requires units from largest to smallest (years, months, weeks, days, hours, minutes, seconds, ...). If a unit's index is less than or equal to the previously parsed unit's index (and not a duplicate), the literal is invalid.
Source
Thrown at src/java/org/apache/cassandra/cql3/functions/types/Duration.java:605
"Invalid duration. The total number of %s must be less or equal to %s",
unitName,
Integer.MAX_VALUE);
}
/**
* Validates that the duration values are added in the proper order.
*
* @param unitIndex the unit index (e.g. years=1, months=2, ...)
*/
private void validateOrder(int unitIndex)
{
if (unitIndex == currentUnitIndex)
throw new IllegalArgumentException(
String.format(
"Invalid duration. The %s are specified multiple times", getUnitName(unitIndex)));
if (unitIndex <= currentUnitIndex)
throw new IllegalArgumentException(
String.format(
"Invalid duration. The %s should be after %s",
getUnitName(currentUnitIndex), getUnitName(unitIndex)));
currentUnitIndex = unitIndex;
}
/**
* Returns the name of the unit corresponding to the specified index.
*
* @param unitIndex the unit index
* @return the name of the unit corresponding to the specified index.
*/
private String getUnitName(int unitIndex)
{
switch (unitIndex)
{
case 1:View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Reorder the components from largest unit to smallest (e.g. '3d 1y' -> '1y 3d')
- Split and sort the duration string by unit rank before passing it to Duration.from
- Catch IllegalArgumentException and show the expected ordering rule to the user
Example fix
// before
Duration.from("5s 2h 1d")
// after
Duration.from("1d 2h 5s") Defensive patterns
Strategy: validation
Validate before calling
private static final java.util.Map<String,Integer> RANK = java.util.Map.of("y",1,"mo",2,"w",3,"d",4,"h",5,"m",6,"s",7,"ms",8,"us",9,"ns",10);
static boolean unitsInOrder(String dur) {
java.util.List<Integer> r = new java.util.ArrayList<>();
java.util.regex.Matcher m = java.util.regex.Pattern.compile("(\\d+)(y|mo|w|d|h|m|s|ms|us|ns)").matcher(dur);
while (m.find()) r.add(RANK.get(m.group(2)));
for (int i = 1; i < r.size(); i++) if (r.get(i) <= r.get(i-1)) return false;
return true;
} Try / catch
try { Duration d = Duration.from(input); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Duration units must appear largest-to-smallest: " + input, e); } Prevention
- Always write duration components largest to smallest: y, mo, w, d, h, m, s, ms, us, ns
- Sort parsed components by unit rank before serialization
- Display the ordering rule in any UI accepting duration input
When it happens
Trigger: Parsing strings like Duration.from("3d 1y") or "5s 2h" — any literal where a smaller unit precedes a larger one, passed to Duration.from or used as a duration literal in CQL.
Common situations: Users writing durations in natural (ascending) order; i18n conventions where small units come first; code that sorts unit components alphabetically instead of by magnitude.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
Related errors
- Unable to convert '%s' to a duration
- Unknown duration symbol '%s'
- Invalid duration. The %s are specified multiple times
- Invalid value for system property: expected integer value bu
- Invalid value for system property: expected long value but g
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/6f1fc4435885e45c.
Report an issue: GitHub.