apache/cassandra · error · InvalidRequestException

Cannot use with

Error message

Cannot use %s with %s

What it means

Thrown from the StatementRestrictions constructor when an UPDATE or DELETE WHERE clause uses an operator that requires filtering/indexing on clustering columns (e.g. non-equality operators like >, <, IN on non-full primary key). Modifications only support exact primary-key restrictions; such operators would need a scan to pick rows, which is disallowed.

Solutions

  1. Restrict the WHERE clause to full equality on all primary key columns (partition key + clustering key).
  2. To delete a range, first SELECT the exact primary keys (with ALLOW FILTERING if needed), then issue one DELETE per key.
  3. Redesign the schema so the rows you want to modify share a directly addressable primary key, or use a secondary table.
  4. Use TTL or partition deletion if the intent is bulk expiry of data.

Example fix

// before
UPDATE t SET v = 1 WHERE k = 0 AND c > 1;
// after
SELECT k, c FROM t WHERE k = 0 AND c > 1 ALLOW FILTERING;
-- then per row:
UPDATE t SET v = 1 WHERE k = 0 AND c = ?;
Defensive patterns

Strategy: validation

Validate before calling

// ensure every primary key column has an equality restriction before UPDATE/DELETE
if (!hasFullPrimaryKeyEquality(restrictions)) throw new IllegalStateException("UPDATE/DELETE requires full primary key equality");

Try / catch

try { session.execute(update); } catch (InvalidRequestException e) { if (e.getMessage().startsWith("Cannot use")) fallbackToSelectThenDelete(); else throw e; }

Prevention

When it happens

Trigger: `UPDATE t SET v=1 WHERE k=0 AND c>1`, `DELETE FROM t WHERE k=0 AND c IN (1,2)` on non-full clustering key, or any ALLOW FILTERING-style relation in an UPDATE/DELETE WHERE clause.

Common situations: Porting SELECT patterns (range/IN restrictions) directly to UPDATE/DELETE; trying to bulk-delete a range of clustering rows; scripts generated from SELECT queries reused for cleanup.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

                                            ? IndexRegistry.obtain(table)
                                            : null;
        /*
         * WHERE clause. For a given entity, rules are:
         *   - EQ relation conflicts with anything else (including a 2nd EQ)
         *   - Can't have more than one LT(E) relation (resp. GT(E) relation)
         *   - IN relation are restricted to row keys (for now) and conflicts with anything else (we could
         *     allow two IN for the same entity but that doesn't seem very useful)
         *   - The value_alias cannot be restricted in any way (we don't support wide rows with indexed value
         *     in CQL so far)
         *   - CONTAINS and CONTAINS_KEY cannot be used with UPDATE or DELETE
         */
        for (Relation relation : whereClause.relations)
        {

            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);

View on GitHub (pinned to 88fd0f6a0e)