apache/cassandra · error · InvalidRequestException

Secondary indexes on materialized views aren't supported

Error message

Secondary indexes on materialized views aren't supported

What it means

Thrown while applying CREATE INDEX when the target relation resolved via getTableOrViewNullable() turns out to be a materialized view (table.isView()). Secondary indexes can only be created on base tables; indexing a view is not supported, so the statement is rejected with this sentinel error (MATERIALIZED_VIEWS_NOT_SUPPORTED) rather than attempting index creation.

Solutions

  1. Create the index on the base table instead, or model the lookup as another materialized view.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java:175 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

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

            throw ire(KEYSPACE_DOES_NOT_EXIST, keyspaceName);

        TableMetadata table = keyspace.getTableOrViewNullable(tableName);
        if (null == table)
            throw ire(TABLE_DOES_NOT_EXIST, tableName);

        if (null != indexName && keyspace.hasIndex(indexName))
        {
            if (ifNotExists)
                return schema;

            throw ire(INDEX_ALREADY_EXISTS, indexName);
        }

        if (table.isCounter())
            throw ire(COUNTER_TABLES_NOT_SUPPORTED);

        if (table.isView())
            throw ire(MATERIALIZED_VIEWS_NOT_SUPPORTED);

        if (keyspace.replicationStrategy.hasTransientReplicas())
            throw new InvalidRequestException(TRANSIENTLY_REPLICATED_KEYSPACE_NOT_SUPPORTED);

        // guardrails to limit number of secondary indexes per table.
        Guardrails.secondaryIndexesPerTable.guard(table.indexes.size() + 1,
                                                  Strings.isNullOrEmpty(indexName)
                                                  ? String.format("on table %s", table.name)
                                                  : String.format("%s on table %s", indexName, table.name),
                                                  false,
                                                  state);

        List<IndexTarget> indexTargets = Lists.newArrayList(transform(rawIndexTargets, t -> t.prepare(table)));

        if (indexTargets.isEmpty() && !attrs.isCustom)
            throw ire(CUSTOM_CREATE_WITHOUT_COLUMN);

        if (indexTargets.size() > 1)

View on GitHub (pinned to 88fd0f6a0e)