{"record":{"id":"588f4f7ee78505c1","repo":"apache/cassandra","slug":"non-primary-key-columns-found-in-where-clause-s","errorCode":null,"errorMessage":"Non PRIMARY KEY columns found in where clause: %s ","messagePattern":"Non PRIMARY KEY columns found in where clause: (.+?) ","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java","lineNumber":319,"sourceCode":"                                             allowFiltering);\n\n        // Covers indexes on the first clustering column (among others).\n        if (isKeyRange && hasQueriableClusteringColumnIndex)\n            usesSecondaryIndexing = true;\n\n        if (usesSecondaryIndexing || clusteringColumnsRestrictions.needFiltering())\n            filterRestrictions.add(clusteringColumnsRestrictions);\n\n        // Even if usesSecondaryIndexing is false at this point, we'll still have to use one if\n        // there is restrictions not covered by the PK.\n        if (!nonPrimaryKeyRestrictions.isEmpty())\n        {\n            if (!type.allowNonPrimaryKeyInWhereClause())\n            {\n                Collection<ColumnIdentifier> nonPrimaryKeyColumns =\n                        ColumnMetadata.toIdentifiers(nonPrimaryKeyRestrictions.columns());\n\n                throw invalidRequest(\"Non PRIMARY KEY columns found in where clause: %s \",\n                                     Joiner.on(\", \").join(nonPrimaryKeyColumns));\n            }\n\n            Optional<SingleRestriction> annRestriction = Streams.stream(nonPrimaryKeyRestrictions)\n                                                                .filter(SingleRestriction::isANN)\n                                                                .findFirst();\n            if (annRestriction.isPresent())\n            {\n                // If there is an ANN restriction then it must be for a vector<float, n> column, and it must have an index\n                ColumnMetadata annColumn = annRestriction.get().firstColumn();\n\n                if (!annColumn.type.isVector() || !(((VectorType<?>)annColumn.type).elementType instanceof FloatType))\n                    throw invalidRequest(ANN_ONLY_SUPPORTED_ON_VECTOR_MESSAGE);\n                if (indexRegistry == null || indexRegistry.listIndexes().stream().noneMatch(i -> i.dependsOn(annColumn)))\n                    throw invalidRequest(ANN_REQUIRES_INDEX_MESSAGE);\n                // We do not allow ANN queries using partition key restrictions that need filtering\n                if (partitionKeyRestrictions.needFiltering())\n                    throw invalidRequest(ANN_REQUIRES_INDEXED_FILTERING_MESSAGE);","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java#L301-L337","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Restrict the WHERE clause to primary key columns only.","Add ALLOW FILTERING for ad-hoc queries on small tables (warning: full scan).","Create a secondary index on the regular column if the query is frequent.","Denormalize into a new table whose primary key includes the filtered column (query-driven modeling)."],"exampleFix":"// before\nSELECT * FROM t WHERE status = 'active';\n// after\nCREATE INDEX ON t (status);\nSELECT * FROM t WHERE status = 'active';","handlingStrategy":"validation","validationCode":"Set<String> pkCols = table.getPrimaryKeyColumns().stream().map(ColumnMetadata::getName).collect(toSet());\nwhereColumns.forEach(c -> { if (!pkCols.contains(c)) throw new IllegalArgumentException(\"non-PK column in WHERE: \" + c); });","typeGuard":null,"tryCatchPattern":"try { session.execute(query); } catch (InvalidRequestException e) { if (e.getMessage().contains(\"Non PRIMARY KEY columns\")) retryWithAllowFilteringOrIndex(); else throw e; }","preventionTips":["Design schemas around known queries (query-driven modeling).","Index or denormalize any column frequently used in WHERE.","Gate ALLOW FILTERING behind explicit opt-in flags."],"tags":["cql","invalid-request","primary-key","where-clause"],"backgroundTag":"invalid-query-parameter","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}