apache/cassandra · error · MarshalException
Unknown duration symbol '%s'
Error message
Unknown duration symbol '%s'
What it means
Duration.add throws this MarshalException when parsing a CQL duration string (standard format like '1h30m') and the unit suffix following a number is not one of the recognized symbols (y/mo/w/d/h/s/ms/us/µs/ns). Cassandra cannot map the suffix to a time period, so the duration value is rejected.
Source
Thrown at src/java/org/apache/cassandra/cql3/Duration.java:269
}
private static Builder add(Builder builder, long number, String symbol)
{
switch (toLowerCaseLocalized(symbol))
{
case "y": return builder.addYears(number);
case "mo": return builder.addMonths(number);
case "w": return builder.addWeeks(number);
case "d": return builder.addDays(number);
case "h": return builder.addHours(number);
case "m": return builder.addMinutes(number);
case "s": return builder.addSeconds(number);
case "ms": return builder.addMillis(number);
case "us":
case "µs": return builder.addMicros(number);
case "ns": return builder.addNanos(number);
}
throw new MarshalException(String.format("Unknown duration symbol '%s'", symbol));
}
public int getMonths()
{
return months;
}
public int getDays()
{
return days;
}
public long getNanoseconds()
{
return nanoseconds;
}
/**View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Use only valid symbols: y, mo, w, d, h, s, ms, us (or µs), ns
- Replace 'sec' with 's', 'min' with 'm' (minutes don't exist as a symbol; use '60s')
- Remember 'm' = months, not minutes; express minutes as seconds (e.g. '90s')
- Use ISO-8601 alternative format (P...T...) if preferred
Example fix
// before INSERT INTO t (k, d) VALUES (1, '90min'); // after INSERT INTO t (k, d) VALUES (1, '1h30m');
Defensive patterns
Strategy: validation
Validate before calling
private static final java.util.regex.Pattern DURATION = java.util.regex.Pattern.compile("^\\d+(y|mo|w|d|h|s|ms|us|µs|ns)+$");
boolean validDuration(String s) { return s != null && DURATION.matcher(s).matches(); } Try / catch
try { insertDuration(value); } catch (InvalidRequestException | MarshalException e) { throw new IllegalArgumentException("Bad duration: " + value, e); } Prevention
- Only use symbols y, mo, w, d, h, s, ms, us, ns
- Express minutes as seconds (e.g. 90s) since 'm' means months
- Prefer ISO-8601 format (P...T...) for clarity
- Unit-test duration parsing for all user-facing inputs
When it happens
Trigger: Inserting/updating a duration column with a value like '1x', '5sec', or '2mth' via prepared statement bind, string literal, or Duration.from parsing; any path reaching parseStandardFormat with an unrecognized trailing symbol.
Common situations: Confusing duration units with ISO-8601 (P1Y2M) or human units like 'sec'/'min'; typos in unit suffixes; users expecting 'm' to mean minutes (it means months).
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
- Durations are not allowed inside sets:
- Durations are not allowed as map keys:
- (dynamic MarshalException message)
- ex.getMessage()
- Unable to convert '%s' to a duration
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d51a9651089751d9.
Report an issue: GitHub.