apache/cassandra · error · InvalidRequestException
Clustering key columns must exactly match columns in CLUSTER
Error message
Clustering key columns must exactly match columns in CLUSTERING ORDER BY directive
What it means
Clustering key columns of a materialized view must be restricted by IS NOT NULL in the view definition's WHERE clause. A NULL clustering value cannot exist as a view row (the key must be fully bound), so validation requires an explicit non-null restriction for each clustering column.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java:270
if (type.isMultiCell())
{
if (type.isCollection())
throw ire("Invalid non-frozen collection type '%s' for PRIMARY KEY column '%s'", type, name);
else
throw ire("Invalid non-frozen user-defined type '%s' for PRIMARY KEY column '%s'", type, name);
}
if (type.isCounter())
throw ire("counter type is not supported for PRIMARY KEY column '%s'", name);
if (type.referencesDuration())
throw ire("duration type is not supported for PRIMARY KEY column '%s'", name);
});
// If we give a clustering order, we must explicitly do so for all aliases and in the order of the PK
if (!clusteringOrder.isEmpty() && !clusteringColumns.equals(new ArrayList<>(clusteringOrder.keySet())))
throw ire("Clustering key columns must exactly match columns in CLUSTERING ORDER BY directive");
/*
* We need to include all of the primary key columns from the base table in order to make sure that we do not
* overwrite values in the view. We cannot support "collapsing" the base table into a smaller number of rows in
* the view because if we need to generate a tombstone, we have no way of knowing which value is currently being
* used in the view and whether or not to generate a tombstone. In order to not surprise our users, we require
* that they include all of the columns. We provide them with a list of all of the columns left to include.
*/
List<ColumnIdentifier> missingPrimaryKeyColumns =
Lists.newArrayList(filter(transform(table.primaryKeyColumns(), c -> c.name), c -> !primaryKeyColumns.contains(c)));
if (!missingPrimaryKeyColumns.isEmpty())
{
throw ire("Cannot create materialized view '%s' without primary key columns %s from base table '%s'",
viewName, join(", ", transform(missingPrimaryKeyColumns, ColumnIdentifier::toString)), tableName);
}
Set<ColumnIdentifier> regularBaseTableColumnsInViewPrimaryKey = new HashSet<>(primaryKeyColumns);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Add IS NOT NULL restrictions in WHERE for every clustering column in the view's primary key
- Verify all key columns appear in both the SELECT list and WHERE IS NOT NULL clauses before applying
Example fix
// before CREATE MATERIALIZED VIEW mv AS SELECT pk, ck, v FROM base WHERE pk IS NOT NULL PRIMARY KEY (pk, ck); // after CREATE MATERIALIZED VIEW mv AS SELECT pk, ck, v FROM base WHERE pk IS NOT NULL AND ck IS NOT NULL PRIMARY KEY (pk, ck);
Defensive patterns
Strategy: validation
Validate before calling
for (String ck : viewClusteringCols) if (!whereRestrictions.contains(ck + " IS NOT NULL")) throw new IllegalArgumentException("Missing IS NOT NULL for clustering column: " + ck); Try / catch
try { session.execute(createMvStmt); } catch (InvalidQueryException e) { if (e.getMessage().contains("IS NOT NULL")) { /* add missing restrictions */ } } Prevention
- Always append IS NOT NULL for every key column in MV WHERE clauses
- Generate WHERE restrictions together with the PRIMARY KEY clause to avoid drift
When it happens
Trigger: CREATE MATERIALIZED VIEW ... WHERE pk IS NOT NULL PRIMARY KEY (pk, ck) where ck (a view clustering column) has no 'ck IS NOT NULL' restriction.
Common situations: Only restricting the partition key and forgetting clustering columns; dropping one of several IS NOT NULL clauses when editing the view definition; generated DDL omitting a restriction.
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
- Cannot create materialized view '%s' without primary key col
- Primary key columns %s must be restricted with 'IS NOT NULL'
- Load CIDR groups cache operation not supported by %s
- 'Get CIDR groups for IP' operation not supported by %s
- ACCESS TO DATACENTERS operations not supported by AllowAllNe
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/bee9d5d93eedbe7f.
Report an issue: GitHub.