apache/cassandra · error · InvalidRequestException

PRIMARY KEY column "%s" cannot be restricted as preceding co

Error message

PRIMARY KEY column "%s" cannot be restricted as preceding column "%s" is not restricted

What it means

Clustering columns must be restricted in primary-key order without gaps: you may only restrict clustering column i if all columns before it are also restricted. When a restricted column skips over an unrestricted preceding clustering column, this error names both columns.

Source

Thrown at src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java:705

            if (hasClusteringColumnsRestrictions() && clusteringColumnsRestrictions.needFiltering())
            {
                if (hasQueriableIndex || forView)
                {
                    usesSecondaryIndexing = true;
                }
                else if (!allowFiltering)
                {
                    List<ColumnMetadata> clusteringColumns = table.clusteringColumns();
                    List<ColumnMetadata> restrictedColumns = new ArrayList<>(clusteringColumnsRestrictions.columns());

                    for (int i = 0, m = restrictedColumns.size(); i < m; i++)
                    {
                        ColumnMetadata clusteringColumn = clusteringColumns.get(i);
                        ColumnMetadata restrictedColumn = restrictedColumns.get(i);

                        if (!clusteringColumn.equals(restrictedColumn))
                        {
                            throw invalidRequest("PRIMARY KEY column \"%s\" cannot be restricted as preceding column \"%s\" is not restricted",
                                                 restrictedColumn.name,
                                                 clusteringColumn.name);
                        }
                    }
                }
            }

        }
    }

    /**
     * Returns the clustering columns that are not restricted.
     * @return the clustering columns that are not restricted.
     */
    private Collection<ColumnIdentifier> getUnrestrictedClusteringColumns()
    {
        List<ColumnMetadata> missingClusteringColumns = new ArrayList<>(table.clusteringColumns());
        missingClusteringColumns.removeAll(new LinkedList<>(clusteringColumnsRestrictions.columns()));

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Add the missing preceding restriction: WHERE pk = ... AND c1 = ... AND c2 = ...
  2. Use the token/partition design so the high-selectivity column comes first in the PRIMARY KEY definition
  3. Restrict c1 with an IN list if you don't know its exact value: WHERE pk = ... AND c1 IN (...) AND c2 = ...
  4. If filtering is genuinely needed, add ALLOW FILTERING (performs a scan within partitions)

Example fix

// before
SELECT * FROM events WHERE device_id = 'd1' AND minute = 42;  -- hour (first clustering col) skipped
// after
SELECT * FROM events WHERE device_id = 'd1' AND hour = 1 AND minute = 42;
Defensive patterns

Strategy: validation

Validate before calling

// Verify restricted clustering columns form a prefix of the clustering order:
List<String> clusteringOrder = table.getClusteringColumns().stream().map(ColumnMetadata::getName).collect(Collectors.toList());
List<String> restricted = whereColumns.stream().filter(clusteringOrder::contains).collect(Collectors.toList());
if (!clusteringOrder.subList(0, restricted.size()).equals(restricted.stream().sorted(Comparator.comparingInt(clusteringOrder::indexOf)).collect(Collectors.toList()))) throw new IllegalArgumentException("Clustering columns must be restricted in order without gaps");

Prevention

When it happens

Trigger: SELECT * FROM t WHERE pk = 'a' AND c2 = 'x' while c1 (which precedes c2 in the PRIMARY KEY) is unrestricted; same gap pattern in DELETEs or IN relations.

Common situations: Querying the 'second' clustering key directly — a common modeling mistake; schema changes that reordered clustering columns; multi-column WHERE clauses generated from ORM filters.

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/bdce5c00d0193d59. Report an issue: GitHub.