apache/cassandra · error · InvalidRequestException
Secondary indexes are not supported on compact value column…
Error message
Secondary indexes are not supported on compact value column of COMPACT STORAGE tables
What it means
For COMPACT STORAGE tables the single hidden/compact value column holds the thrift-encoded cell value; it is not indexable by a legacy secondary index. When the index target equals `compactTable.compactValueColumn`, InvalidRequestException (COMPACT_COLUMN_IN_COMPACT_STORAGE) is thrown.
Solutions
- Drop COMPACT STORAGE (`ALTER TABLE ... DROP COMPACT STORAGE`) so the value becomes a normal column, then create the index.
- Restructure queries to filter by primary key, or migrate the data into a modern table where the value column is a regular column and can be indexed.
- Consider SAI (if the version supports it) after dropping compact storage.
Example fix
-- before CREATE INDEX ON legacy_compact (value); -- value is the compact value column -- after ALTER TABLE legacy_compact DROP COMPACT STORAGE; CREATE INDEX ON legacy_compact (value);
Defensive patterns
Strategy: validation
Validate before calling
TableMetadata t = session.getCluster().getMetadata().getKeyspace("ks").getTable("t");
if (t.getOptions().getCompactStorage())
throw new IllegalStateException("create index on compact value column not supported; DROP COMPACT STORAGE first"); Try / catch
try { session.execute(createIndex); }
catch (InvalidQueryException e) {
if (e.getMessage().contains("compact value column"))
throw new IllegalStateException("ALTER TABLE ... DROP COMPACT STORAGE, then index the column", e);
throw e;
} Prevention
- Identify the compact value column (single non-key column in thrift tables) before writing index DDL
- Treat COMPACT STORAGE tables as indexing-hostile; migrate them first
- Never auto-generate indexes for every column of legacy compact tables
When it happens
Trigger: `CREATE INDEX ... ON compact_table (value_column)` where the named column is the compact value column of a `WITH COMPACT STORAGE` table (the column written via thrift `insert` or exposed as the single non-key column).
Common situations: Legacy thrift tables where users attempt to index the sole value column to speed up lookups; automated DDL generated from thrift metadata.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Secondary indexes are not supported on PRIMARY KEY columns…
- Cannot add new column to a COMPACT STORAGE table
- Cannot create ENTRIES index on frozen map clustering column
- Cannot create index on
- Cannot create () index on frozen column . Frozen…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/51c930188afc4ebe.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java:285
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);
}
if (column.isPartitionKey() && table.partitionKeyColumns().size() == 1)
throw ire(ONLY_PARTITION_KEY, column);
if (target.type == Type.FULL && isNonSAIIndex && (!baseType.isCollection() || column.type.isMultiCell()))
throw ire(FULL_ON_FROZEN_COLLECTIONS);
if (!baseType.isCollection() && target.type != Type.SIMPLE)
throw ire(NON_COLLECTION_SIMPLE_INDEX, target.type, column);
// Frozen collections are only supported with SAI indexes.
if (isNonSAIIndex && baseType.isCollection() && !column.type.isMultiCell())
{
if (target.type == Type.VALUES || target.type == Type.KEYS || target.type == Type.KEYS_AND_VALUES)
{
throw ire(CREATE_ON_FROZEN_COLUMN, target.type.toString(), column.name, column.name);
}View on GitHub (pinned to 88fd0f6a0e)