apache/cassandra · error · InvalidRequestException
Invalid restrictions on clustering columns since the
Error message
Invalid restrictions on clustering columns since the %s statement modifies only static columns
What it means
Thrown when an UPDATE or DELETE that modifies only static columns includes restrictions on clustering columns. Since a static-column write applies to the whole partition, clustering restrictions are semantically meaningless (they don't narrow which rows are modified), so Cassandra rejects them.
Solutions
- Remove the clustering column restrictions and restrict only the partition key: `UPDATE t SET s=3 WHERE k=0`.
- If per-clustering-row modification is intended, move the column out of static so it becomes a regular column.
- If a per-row static 'view' is needed, split into two tables: one keyed for static data, one for clustering rows.
- Use SELECT-only restriction or a DELETE of regular columns pattern if the intent was row deletion, not static modification.
Example fix
// before UPDATE t SET s = 3 WHERE k = 0 AND c = 1; -- s is static // after UPDATE t SET s = 3 WHERE k = 0;
Defensive patterns
Strategy: validation
Validate before calling
// strip clustering restrictions when only static columns are modified
if (modifiesOnlyStaticColumns(stmt) && hasClusteringRestrictions(whereClause)) throw new IllegalArgumentException("static-column write cannot restrict clustering columns"); Prevention
- Remember static values are per-partition; write them with partition-key-only WHERE.
- Avoid making columns static unless the write model is truly partition-wide.
- Assert at query-construction time that modified columns match restriction scope.
When it happens
Trigger: `UPDATE t SET s=3 WHERE k=0 AND c=1` where s is static and c is clustering; `DELETE s FROM t WHERE k=0 AND c=1`; any statement whose modified columns are all static while the WHERE clause restricts clustering columns.
Common situations: Developers assuming static-column updates apply per-row; migration from a table where the column was not static; code-generation bugs that always append clustering predicates.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot restrict clustering columns when selecting only…
- A TTL must be greater or equal to 0, but was
- Attempted to delete an element from a list which is null
- Cannot mix IF conditions and
- Cannot set on non-regular table ' .
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/5b1c1ca4a960c34d.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java:292
// Some but not all of the partition key columns have been specified;
// hence we need turn these restrictions into a row filter.
if (usesSecondaryIndexing || partitionKeyRestrictions.needFiltering())
filterRestrictions.add(partitionKeyRestrictions);
if (selectsOnlyStaticColumns && hasClusteringColumnsRestrictions())
{
// If the only updated/deleted columns are static, then we don't need clustering columns.
// And in fact, unless it is an INSERT, we reject if clustering colums are provided as that
// suggest something unintended. For instance, given:
// CREATE TABLE t (k int, v int, s int static, PRIMARY KEY (k, v))
// it can make sense to do:
// INSERT INTO t(k, v, s) VALUES (0, 1, 2)
// but both
// UPDATE t SET s = 3 WHERE k = 0 AND v = 1
// DELETE v FROM t WHERE k = 0 AND v = 1
// sounds like you don't really understand what your are doing.
if (type.isDelete() || type.isUpdate())
throw invalidRequest("Invalid restrictions on clustering columns since the %s statement modifies only static columns",
type);
if (type.isSelect())
throw invalidRequest("Cannot restrict clustering columns when selecting only static columns");
}
processClusteringColumnsRestrictions(hasQueriableIndex,
selectsOnlyStaticColumns,
forView,
allowFiltering);
// Covers indexes on the first clustering column (among others).
if (isKeyRange && hasQueriableClusteringColumnIndex)
usesSecondaryIndexing = true;
if (usesSecondaryIndexing || clusteringColumnsRestrictions.needFiltering())
filterRestrictions.add(clusteringColumnsRestrictions);
// Even if usesSecondaryIndexing is false at this point, we'll still have to use one ifView on GitHub (pinned to 88fd0f6a0e)