apache/cassandra · error · InvalidRequestException

Durations are not allowed inside sets:

Error message

Durations are not allowed inside sets: 

What it means

Duration values (org.apache.cassandra.db.marshal.DurationType) are forbidden as elements of SET collections. Durations have no natural total ordering (e.g. 1mo vs 30d), which sets require for uniqueness and sorting.

Source

Thrown at src/java/org/apache/cassandra/cql3/CQL3Type.java:868

            public CQL3Type prepareInternal(String keyspace, Types udts)
            {
                return prepare(keyspace, udts, true);
            }

            public CQL3Type prepare(String keyspace, Types udts, boolean isInternal) throws InvalidRequestException
            {
                assert values != null : "Got null values type for a collection";

                if (!frozen && values.supportsFreezing() && !values.frozen)
                    throwNestedNonFrozenError(values);

                // we represent supercolumns as maps, internally, and we do allow counters in supercolumns. Thus,
                // for internal type parsing (think schema) we have to make an exception and allow counters as (map) values
                if (values.isCounter() && !isInternal)
                    throw new InvalidRequestException("Counters are not allowed inside collections: " + this);

                if (values.isDuration() && kind == Kind.SET)
                    throw new InvalidRequestException("Durations are not allowed inside sets: " + this);

                if (keys != null)
                {
                    if (keys.isCounter())
                        throw new InvalidRequestException("Counters are not allowed inside collections: " + this);
                    if (keys.isDuration())
                        throw new InvalidRequestException("Durations are not allowed as map keys: " + this);
                    if (!frozen && keys.supportsFreezing() && !keys.frozen)
                        throwNestedNonFrozenError(keys);
                }

                AbstractType<?> valueType = values.prepare(keyspace, udts).getType();
                switch (kind)
                {
                    case LIST:
                        return new Collection(ListType.getInstance(valueType, !frozen));
                    case SET:
                        return new Collection(SetType.getInstance(valueType, !frozen));

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use `list<duration>` or `frozen<list<duration>>` instead of a set — lists allow durations
  2. Store durations as their string/interval representation in a set<text> if ordering does not matter
  3. Use a single duration column if only one value is needed

Example fix

// before
CREATE TABLE t (id uuid PRIMARY KEY, offsets set<duration>);
// after
CREATE TABLE t (id uuid PRIMARY KEY, offsets frozen<list<duration>>);
Defensive patterns

Strategy: validation

Validate before calling

boolean usesDurationInSet(String cqlTypeDecl) {
    return cqlTypeDecl.toLowerCase().replaceAll("\\s+","").matches("set<.*duration.*");
}

Try / catch

try { session.execute(ddl); } catch (InvalidQueryException e) { if (e.getMessage().startsWith("Durations are not allowed inside sets")) { /* switch set to list or frozen<list> */ } else throw e; }

Prevention

When it happens

Trigger: Declaring a column `set<duration>` in CREATE TABLE or ALTER TABLE, or embedding duration inside a non-frozen set type.

Common situations: Users attempting to store sets of durations computed from interval data; mistyping `duration` where `time` or a frozen list of durations was intended.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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