apache/cassandra · error · InvalidRequestException

Secondary indexes are not supported on collections containin

Error message

Secondary indexes are not supported on collections containing durations

What it means

Cassandra rejects creating a secondary index on a collection column (list/set/map) whose element, key, or value type is or contains `duration`. Durations are not orderable/comparable in the way index backends require, so indexing collections containing them is disallowed. The check fires in validateIndexTarget when the target column type references duration and is a collection.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java:268

    private void validateIndexTarget(TableMetadata table, IndexMetadata.Kind kind, IndexTarget target, IndexAttributes attrs)
    {
        ColumnMetadata column = table.getColumn(target.column);

        if (null == column)
            throw ire(COLUMN_DOES_NOT_EXIST, target.column);

        AbstractType<?> baseType = column.type.unwrap();

        boolean isNonSAIIndex = !isSAIIndex(attrs);

        // TODO: this check needs to be removed with CASSANDRA-20235
        if ((kind == IndexMetadata.Kind.CUSTOM))
            validateCustomIndexColumnName(target.column.toString());

        if (column.type.referencesDuration())
        {
            if (column.type.isCollection())
                throw ire(COLLECTIONS_WITH_DURATIONS_NOT_SUPPORTED);

            if (column.type.isTuple())
                throw ire(TUPLES_WITH_DURATIONS_NOT_SUPPORTED);

            if (column.type.isUDT())
                throw  ire(UDTS_WITH_DURATIONS_NOT_SUPPORTED);

            throw ire(DURATIONS_NOT_SUPPORTED);
        }

        if (table.isCompactTable())
        {
            TableMetadata.CompactTableMetadata compactTable = (TableMetadata.CompactTableMetadata) table;
            if (column.isPrimaryKeyColumn())
                throw new InvalidRequestException(PRIMARY_KEY_IN_COMPACT_STORAGE);
            if (compactTable.compactValueColumn.equals(column))
                throw new InvalidRequestException(COMPACT_COLUMN_IN_COMPACT_STORAGE);
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove duration from the collection's type parameters (use timestamp/bigint for instants, or store total milliseconds).
  2. Denormalize: store the duration-derived value as a separate indexed column (e.g. bigint seconds) alongside the collection.
  3. Query without a secondary index: filter client-side or model the data so lookups use partition/clustering keys instead.

Example fix

// before
CREATE INDEX ON events (tags); // tags: map<text, duration>
// after
ALTER TABLE events ADD tag_seconds map<text, bigint>;
CREATE INDEX ON events (tag_seconds);
Defensive patterns

Strategy: validation

Validate before calling

function canIndexCollection(type) {
  return type.isCollection() ? !type.referencesDuration() : !type.referencesDuration();
}
if (column.type.isCollection() && column.type.referencesDuration()) throw new Error('unindexable: collection contains duration');

Type guard

const isIndexableCollection = (t) => t.isCollection() && !t.referencesDuration();

Try / catch

try { session.execute("CREATE INDEX ON t (col)"); } catch (e) { if (/not supported on collections containing durations/.test(e.message)) { /* remodel column type */ } else throw e; }

Prevention

When it happens

Trigger: CREATE INDEX / CREATE CUSTOM INDEX whose target is a list<duration>, set<duration>, map<duration, X>, map<X, duration>, or a frozen/multi-cell collection nesting duration (including via UDT/tuple elements), e.g. `CREATE INDEX ON t (full(map_col))` where map_col is frozen<map<text, duration>>.

Common situations: Schema migrations adding duration fields to tracked interval data then trying to index the collection for queries; using duration inside map values for time-budget per-key lookups; copying an index DDL from a table where the column was timestamp.

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/8a067de938de7927. Report an issue: GitHub.