apache/cassandra · error · IllegalArgumentException

Invalid duration. The %s are specified multiple times

Error message

Invalid duration. The %s are specified multiple times

What it means

Thrown by Duration.Builder.validateOrder when the same duration unit appears more than once in a single duration literal. The builder tracks the index of the last unit parsed; if the next unit has the same index, the units are duplicated. Duration syntax requires each unit to appear at most once.

Source

Thrown at src/java/org/apache/cassandra/cql3/functions/types/Duration.java:600

         */
        private void validate(long units, long limit, String unitName)
        {
            checkArgument(
            units <= limit,
            "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.
         */

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove the duplicate unit and merge its values (e.g. '1d 2d' -> '3d')
  2. Pre-validate the duration string with a regex ensuring each unit appears at most once before calling Duration.from
  3. Catch IllegalArgumentException and report which unit was duplicated to the user

Example fix

// before
Duration.from("1y 6mo 1y")
// after
Duration.from("2y 6mo")
Defensive patterns

Strategy: validation

Validate before calling

static boolean hasDuplicateUnits(String dur) {
  java.util.regex.Matcher m = java.util.regex.Pattern.compile("(y|mo|w|d|h|m|s|ms|us|ns)").matcher(dur);
  java.util.Set<String> seen = new java.util.HashSet<>();
  while (m.find()) { if (!seen.add(m.group())) return true; }
  return false;
}

Try / catch

try { Duration d = Duration.from(input); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Malformed duration (duplicate/out-of-order units): " + input, e); }

Prevention

When it happens

Trigger: Parsing strings like Duration.from("1d 2d") or "1mo 2mo 3d" — any duration where a unit symbol is repeated in one literal passed to Duration.from or a duration column insert.

Common situations: Programmatically building duration strings by concatenating components without deduplicating units; user input like '2 years 6 months 1 year'; template bugs that append the same unit twice.

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/6e089bce5c41bb6b. Report an issue: GitHub.