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

  1. Use only valid symbols: y, mo, w, d, h, s, ms, us (or µs), ns
  2. Replace 'sec' with 's', 'min' with 'm' (minutes don't exist as a symbol; use '60s')
  3. Remember 'm' = months, not minutes; express minutes as seconds (e.g. '90s')
  4. 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

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/d51a9651089751d9. Report an issue: GitHub.