{"record":{"id":"52d8d7d15b475b33","repo":"apache/cassandra","slug":"secondary-indexes-are-not-supported-on-tuples-cont","errorCode":null,"errorMessage":"Secondary indexes are not supported on tuples containing durations","messagePattern":"Secondary indexes are not supported on tuples containing durations","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java","lineNumber":271,"sourceCode":"\n        if (null == column)\n            throw ire(COLUMN_DOES_NOT_EXIST, target.column);\n\n        AbstractType<?> baseType = column.type.unwrap();\n\n        boolean isNonSAIIndex = !isSAIIndex(attrs);\n\n        // TODO: this check needs to be removed with CASSANDRA-20235\n        if ((kind == IndexMetadata.Kind.CUSTOM))\n            validateCustomIndexColumnName(target.column.toString());\n\n        if (column.type.referencesDuration())\n        {\n            if (column.type.isCollection())\n                throw ire(COLLECTIONS_WITH_DURATIONS_NOT_SUPPORTED);\n\n            if (column.type.isTuple())\n                throw ire(TUPLES_WITH_DURATIONS_NOT_SUPPORTED);\n\n            if (column.type.isUDT())\n                throw  ire(UDTS_WITH_DURATIONS_NOT_SUPPORTED);\n\n            throw ire(DURATIONS_NOT_SUPPORTED);\n        }\n\n        if (table.isCompactTable())\n        {\n            TableMetadata.CompactTableMetadata compactTable = (TableMetadata.CompactTableMetadata) table;\n            if (column.isPrimaryKeyColumn())\n                throw new InvalidRequestException(PRIMARY_KEY_IN_COMPACT_STORAGE);\n            if (compactTable.compactValueColumn.equals(column))\n                throw new InvalidRequestException(COMPACT_COLUMN_IN_COMPACT_STORAGE);\n        }\n\n        if (column.isPartitionKey() && table.partitionKeyColumns().size() == 1)\n            throw ire(ONLY_PARTITION_KEY, column);","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java#L253-L289","documentation":"Cassandra rejects secondary indexes on tuple columns that contain a `duration` component. Duration cannot participate in index equality/range semantics, so any tuple referencing duration is unindexable. Raised in validateIndexTarget when the column type is a tuple referencing duration.","triggerScenarios":"`CREATE INDEX ON t (tuple_col)` where tuple_col is e.g. frozen<tuple<int, duration>> or tuple<duration, text>, via CREATE INDEX / CREATE CUSTOM INDEX.","commonSituations":"Modeling (offset, duration) pairs in a tuple for range queries then adding an index; upgrading a schema that swapped a timestamp component for duration.","solutions":["Replace the duration component with an indexable numeric type (bigint milliseconds) or timestamp.","Split the tuple into separate columns and index only the non-duration ones.","Use a materialized view / denormalized table keyed by the values you need to query."],"exampleFix":"// before\nCREATE INDEX ON measurements (window); // window frozen<tuple<timestamp, duration>>\n// after\nALTER TABLE measurements ADD window_ms frozen<tuple<timestamp, bigint>>;\nCREATE INDEX ON measurements (window_ms);","handlingStrategy":"validation","validationCode":"if (column.type.isTuple() && column.type.referencesDuration()) throw new Error('unindexable tuple: contains duration');","typeGuard":"const isIndexableTuple = (t) => t.isTuple() && !t.referencesDuration();","tryCatchPattern":"try { session.execute(ddl); } catch (e) { if (/not supported on tuples containing durations/.test(e.message)) { /* replace duration component */ } else throw e; }","preventionTips":["Prefer separate numeric columns over tuples containing duration","Check tuple component types before generating index DDL"],"tags":["cassandra","cql","secondary-index","tuple","duration"],"backgroundTag":"schema-validation-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}