apache/cassandra · error · InvalidRequestException

Operator %s is only supported in intersections for reads tha

Error message

Operator %s is only supported in intersections for reads that do not require replica reconciliation.

What it means

StorageAttachedIndexQueryPlan.create only supports operators that SAI can answer (Expression.supportsOperator) inside strict (replica-reconciled) filters; user-defined expressions are also rejected. When such an expression appears in a non-strict filter context, it throws InvalidRequestException saying the operator is only supported in intersections for reads that don't require replica reconciliation.

Source

Thrown at src/java/org/apache/cassandra/index/sai/plan/StorageAttachedIndexQueryPlan.java:90

        ImmutableSet.Builder<Index> selectedIndexesBuilder = ImmutableSet.builder();

        RowFilter indexFilter = filter;
        RowFilter postIndexFilter = filter;

        for (RowFilter.Expression expression : filter)
        {
            // We ignore any expressions here (user-defined expressions and SAI unsupported operators) where we don't have a way to
            // translate their #isSatifiedBy method, they will be included in the filter returned by 
            // QueryPlan#postIndexQueryFilter(). If strict filtering is not allowed, we must reject the query until the
            // expression(s) in question are compatible with #isSatifiedBy.
            //
            // Note: For both the pre- and post-filters we need to check that the expression exists before removing it
            // because the without method assert if the expression doesn't exist. This can be the case if we are given
            // a duplicate expression - a = 1 and a = 1. The without method removes all instances of the expression.
            if (!Expression.supportsOperator(expression.operator()) || expression.isUserDefined())
            {
                if (!filter.isStrict())
                    throw new InvalidRequestException(String.format(UNSUPPORTED_NON_STRICT_OPERATOR, expression.operator()));

                if (indexFilter.getExpressions().contains(expression))
                    indexFilter = indexFilter.without(expression);
                continue;
            }

            if (postIndexFilter.getExpressions().contains(expression))
                postIndexFilter = postIndexFilter.without(expression);

            for (StorageAttachedIndex index : indexes)
            {
                if (index.supportsExpression(expression) && !filter.indexHints.excludes(index))
                {
                    selectedIndexesBuilder.add(index);
                }
            }
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Restructure the query so SAI predicates form a single intersection without reconciliation-requiring operators
  2. Remove user-defined (custom index) expressions from the SAI query
  3. Change consistency level / query form so replica reconciliation is not required
  4. Use ALLOW FILTERING or a non-indexed path if appropriate

Example fix

// before
SELECT * FROM t WHERE a = 1 AND custom_expr(b) = 'x'; // unsupported operator in strict/reconciliation path
// after
SELECT * FROM t WHERE a = 1; // then post-filter custom expression client-side
Defensive patterns

Strategy: try-catch

Try / catch

try {
    session.execute(cql);
} catch (InvalidRequestException e) {
    if (e.getMessage().contains("only supported in intersections")) {
        // restructure query into strict intersection or post-filter client-side
    }
}

Prevention

When it happens

Trigger: Issuing a query where an SAI operator (or a user-defined expression) appears in a filter position requiring replica reconciliation (e.g. with per-replica reconciliation / non-intersection reads), rather than a plain strict intersection.

Common situations: Mixing SAI-indexed predicates with features that weaken read consistency assumptions (e.g. certain ranges/tombstone-reconciliation reads); using custom index expressions alongside SAI operators; CL tuning (e.g. CL=ONE with strong-consistency features) that triggers reconciliation paths.

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/9f9a3b2dab23dd11. Report an issue: GitHub.