apache/cassandra · error · InvalidRequestException

Custom index expressions cannot be used in WHERE clauses for

Error message

Custom index expressions cannot be used in WHERE clauses for UPDATE or DELETE statements

What it means

In ModificationStatement's restrictions builder, if the WHERE clause of an UPDATE or DELETE contains custom index expressions (e.g. expr(idx, ...)), this InvalidRequestException is thrown. Custom index expressions are only permitted in SELECT statements, never in data-modifying statements.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java:1428

         * Creates the restrictions.
         *
         * @param metadata the table meta data
         * @param boundNames the bound names
         * @param operations the column operations
         * @param where the where clause
         * @param conditions the conditions
         * @return the restrictions
         */
        protected StatementRestrictions newRestrictions(ClientState state,
                                                        TableMetadata metadata,
                                                        VariableSpecifications boundNames,
                                                        Operations operations,
                                                        WhereClause where,
                                                        Conditions conditions,
                                                        Object owner)
        {
            if (where.containsCustomExpressions())
                throw new InvalidRequestException(CUSTOM_EXPRESSIONS_NOT_ALLOWED);

            boolean applyOnlyToStaticColumns = appliesOnlyToStaticColumns(operations, conditions);
            return new StatementRestrictions(state, type, metadata, IndexHints.NONE, where, boundNames, Collections.emptyList(), owner, applyOnlyToStaticColumns, false, false);
        }

        public List<ColumnCondition.Raw> getConditions()
        {
            return conditions;
        }
    }

    private static final Constants.Value ONE = new Constants.Value(ByteBufferUtil.bytes(1));

    public SelectStatement createSelectForTxn()
    {
        // TODO: get working with static-only updates that don't specify any/all primary key columns
        Preconditions.checkState(getRestrictions().hasAllPrimaryKeyColumnsRestrictedByEqualities());
        Selection selection = Selection.forColumns(metadata, Lists.newArrayList(requiresRead), false);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove the custom index expression and identify target rows via primary-key columns instead.
  2. Rewrite as a SELECT to find the keys first, then issue an UPDATE/DELETE on those keys.
  3. Reconsider the data model so the target rows are addressable by their primary key.

Example fix

// before
DELETE FROM t WHERE expr(custom_idx, tags) = 'x';
// after
SELECT pk FROM t WHERE expr(custom_idx, tags) = 'x';
DELETE FROM t WHERE pk = <found key>;
Defensive patterns

Strategy: validation

Validate before calling

if (statementType != SELECT && whereClause.containsCustomIndexExpression()) throw new IllegalArgumentException("custom index expressions only allowed in SELECT");

Prevention

When it happens

Trigger: UPDATE ... WHERE expr(my_index, col) = ... or DELETE with a custom-index expression in the WHERE clause.

Common situations: Copying a SELECT's WHERE clause into an UPDATE/DELETE; ORM/query builders emitting index expressions generically.

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