apache/cassandra · error · InvalidRequestException

Non PRIMARY KEY columns found in where clause

Error message

Non PRIMARY KEY columns found in where clause: %s 

What it means

Thrown when a WHERE clause references non-primary-key (regular) columns in a statement type that does not allow them (e.g. normal SELECT/UPDATE/DELETE without ALLOW FILTERING or a supporting index). Cassandra restricts WHERE clauses to primary key columns unless filtering or indexing is permitted.

Solutions

  1. Restrict the WHERE clause to primary key columns only.
  2. Add ALLOW FILTERING for ad-hoc queries on small tables (warning: full scan).
  3. Create a secondary index on the regular column if the query is frequent.
  4. Denormalize into a new table whose primary key includes the filtered column (query-driven modeling).

Example fix

// before
SELECT * FROM t WHERE status = 'active';
// after
CREATE INDEX ON t (status);
SELECT * FROM t WHERE status = 'active';
Defensive patterns

Strategy: validation

Validate before calling

Set<String> pkCols = table.getPrimaryKeyColumns().stream().map(ColumnMetadata::getName).collect(toSet());
whereColumns.forEach(c -> { if (!pkCols.contains(c)) throw new IllegalArgumentException("non-PK column in WHERE: " + c); });

Try / catch

try { session.execute(query); } catch (InvalidRequestException e) { if (e.getMessage().contains("Non PRIMARY KEY columns")) retryWithAllowFilteringOrIndex(); else throw e; }

Prevention

When it happens

Trigger: `SELECT * FROM t WHERE regular_col = x` without ALLOW FILTERING; WHERE clause on regular columns in UPDATE/DELETE; restricting a regular column in a statement type that disallows non-PK predicates.

Common situations: New users expecting SQL-style WHERE on any column; schema changed so a formerly keyed column became regular; auto-generated predicates including non-key fields.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

                                             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
        // there is restrictions not covered by the PK.
        if (!nonPrimaryKeyRestrictions.isEmpty())
        {
            if (!type.allowNonPrimaryKeyInWhereClause())
            {
                Collection<ColumnIdentifier> nonPrimaryKeyColumns =
                        ColumnMetadata.toIdentifiers(nonPrimaryKeyRestrictions.columns());

                throw invalidRequest("Non PRIMARY KEY columns found in where clause: %s ",
                                     Joiner.on(", ").join(nonPrimaryKeyColumns));
            }

            Optional<SingleRestriction> annRestriction = Streams.stream(nonPrimaryKeyRestrictions)
                                                                .filter(SingleRestriction::isANN)
                                                                .findFirst();
            if (annRestriction.isPresent())
            {
                // If there is an ANN restriction then it must be for a vector<float, n> column, and it must have an index
                ColumnMetadata annColumn = annRestriction.get().firstColumn();

                if (!annColumn.type.isVector() || !(((VectorType<?>)annColumn.type).elementType instanceof FloatType))
                    throw invalidRequest(ANN_ONLY_SUPPORTED_ON_VECTOR_MESSAGE);
                if (indexRegistry == null || indexRegistry.listIndexes().stream().noneMatch(i -> i.dependsOn(annColumn)))
                    throw invalidRequest(ANN_REQUIRES_INDEX_MESSAGE);
                // We do not allow ANN queries using partition key restrictions that need filtering
                if (partitionKeyRestrictions.needFiltering())
                    throw invalidRequest(ANN_REQUIRES_INDEXED_FILTERING_MESSAGE);

View on GitHub (pinned to 88fd0f6a0e)