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

  1. Remove the clustering column restrictions and restrict only the partition key: `UPDATE t SET s=3 WHERE k=0`.
  2. If per-clustering-row modification is intended, move the column out of static so it becomes a regular column.
  3. If a per-row static 'view' is needed, split into two tables: one keyed for static data, one for clustering rows.
  4. 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

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


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 if

View on GitHub (pinned to 88fd0f6a0e)