apache/cassandra · error · InvalidRequestException
restriction is only supported on properly indexed columns…
Error message
%s restriction is only supported on properly indexed columns. %s is not valid.
What it means
Thrown when a relation uses an operator that requires indexing (e.g. CONTAINS, or non-equality operators on regular columns) but no suitable secondary index supports that restriction, or secondary indices are not permitted for this statement type. Cassandra will not perform unindexed scans implicitly.
Solutions
- Create a supporting secondary index: CREATE INDEX ON t (regular_col) (or an index covering the collection/operator used).
- Add ALLOW FILTERING if the table is small and an unindexed scan is acceptable (performance risk on large tables).
- Verify with the index registry/schema that the index actually covers the column and operator used in the relation.
- Model the query instead: denormalize into a query table with the filtered column in the primary key.
Example fix
// before SELECT * FROM t WHERE email = 'a@b.c'; -- no index // after CREATE INDEX ON t (email); SELECT * FROM t WHERE email = 'a@b.c';
Defensive patterns
Strategy: validation
Validate before calling
// before querying, verify an index covers the column
boolean indexed = schemaKeyspaces.get(ks).getTables().get(t).getIndexes().values().stream()
.anyMatch(i -> i.getTarget().equals(columnName));
if (!indexed) { createIndex(); } Try / catch
try { session.execute(query); } catch (InvalidRequestException e) { if (e.getMessage().contains("only supported on properly indexed")) runWithAllowFiltering(); else throw e; } Prevention
- Model tables per query; keep high-frequency predicates in the primary key.
- Check schema metadata for index coverage at startup.
- Reserve ALLOW FILTERING for small tables and ad-hoc analysis.
When it happens
Trigger: `SELECT * FROM t WHERE regular_col = x` without ALLOW FILTERING and without an index; CONTAINS on a collection without a collection index; using such restrictions in statement types that disallow secondary indices; index exists but the relation's operator/column is not covered by it.
Common situations: Querying a column that was never indexed; index created on a different column than the one in the WHERE clause; SASI/SAI vs legacy 2i confusion after upgrades; forgetting ALLOW FILTERING during ad-hoc analysis.
Related errors
- Cannot use with
- A TTL must be greater or equal to 0, but was
- ANN ordering by vector requires all restricted column(s) to…
- Attempted to delete an element from a list which is null
- Cannot create ENTRIES index on frozen map clustering column
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/c3be960d0ea26408.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java:239
Operator operator = relation.operator();
if (operator.requiresFilteringOrIndexingFor(ColumnMetadata.Kind.CLUSTERING) && (type.isUpdate() || type.isDelete()))
{
throw invalidRequest("Cannot use %s with %s", type, operator);
}
if (operator == Operator.IS_NOT)
{
if (!forView)
throw new InvalidRequestException("Unsupported restriction: " + relation);
this.notNullColumns.addAll(relation.toRestriction(table, boundNames, owner, allowFiltering).columns());
}
else if (operator.requiresIndexing())
{
Restriction restriction = relation.toRestriction(table, boundNames, owner, allowFiltering);
if (!type.allowUseOfSecondaryIndices() || !restriction.hasSupportingIndex(indexRegistry, indexHints))
throw invalidRequest("%s restriction is only supported on properly " +
"indexed columns. %s is not valid.", operator, relation);
addRestriction(restriction, indexRegistry, indexHints);
}
else
{
addRestriction(relation.toRestriction(table, boundNames, owner, allowFiltering), indexRegistry, indexHints);
}
}
// ORDER BY clause.
// Some indexes can be used for ordering.
nonPrimaryKeyRestrictions = addOrderingRestrictions(orderings, nonPrimaryKeyRestrictions);
hasRegularColumnsRestrictions = nonPrimaryKeyRestrictions.hasRestrictionFor(ColumnMetadata.Kind.REGULAR);
boolean hasQueriableClusteringColumnIndex = false;
boolean hasQueriableIndex = false;View on GitHub (pinned to 88fd0f6a0e)