apache/cassandra · error · InvalidRequestException

No PRIMARY KEY specifed for view

Error message

No PRIMARY KEY specifed for view '%s' (exactly one required)

What it means

A materialized view must define exactly one PRIMARY KEY specification. Cassandra throws this when the view's PRIMARY KEY clause yields no partition key columns, which happens when the PRIMARY KEY clause is missing or malformed during prepare().

Solutions

  1. Add an explicit PRIMARY KEY clause listing the view's partition key column(s) first, then clustering columns
  2. Ensure every partition key column is also selected and declared IS NOT NULL in the WHERE clause

Example fix

// before
CREATE MATERIALIZED VIEW sales.orders_mv AS SELECT * FROM sales.orders WHERE order_id IS NOT NULL;
// after
CREATE MATERIALIZED VIEW sales.orders_mv AS SELECT * FROM sales.orders WHERE order_id IS NOT NULL PRIMARY KEY (order_id);
Defensive patterns

Strategy: validation

Validate before calling

if (!/PRIMARY\s+KEY\s*\(/i.test(ddl)) throw new Error('CREATE MATERIALIZED VIEW requires a PRIMARY KEY clause');

Try / catch

try { session.execute(ddl); } catch (e) { if (e instanceof InvalidQueryError && /No PRIMARY KEY/.test(e.message)) { /* append PRIMARY KEY clause */ } else throw e; }

Prevention

When it happens

Trigger: CREATE MATERIALIZED VIEW without a PRIMARY KEY clause, or a parenthesized key spec that the grammar did not map to partition key columns.

Common situations: Omitting 'PRIMARY KEY (...)' because normal tables can omit it; malformed nesting of the key tuple; tooling that strips the clause.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java:461

            this.tableName = tableName;
            this.viewName = viewName;
            this.rawColumns = rawColumns;
            this.whereClause = whereClause;
            this.ifNotExists = ifNotExists;
        }

        public CreateViewStatement prepare(ClientState state)
        {
            String keyspaceName = viewName.hasKeyspace() ? viewName.getKeyspace() : state.getKeyspace();

            if (tableName.hasKeyspace() && !keyspaceName.equals(tableName.getKeyspace()))
                throw ire("Cannot create a materialized view on a table in a different keyspace");

            if (!bindVariables.isEmpty())
                throw ire("Bind variables are not allowed in CREATE MATERIALIZED VIEW statements");

            if (null == partitionKeyColumns)
                throw ire("No PRIMARY KEY specifed for view '%s' (exactly one required)", viewName);

            return new CreateViewStatement(keyspaceName,
                                           tableName.getName(),
                                           viewName.getName(),

                                           rawColumns,
                                           partitionKeyColumns,
                                           clusteringColumns,

                                           whereClause,

                                           clusteringOrder,
                                           attrs,

                                           ifNotExists);
        }

        public void setPartitionKeyColumns(List<ColumnIdentifier> columns)

View on GitHub (pinned to 88fd0f6a0e)