apache/cassandra · error · IllegalArgumentException

Unsupported expression during index query:

Error message

Unsupported expression during index query: 

What it means

Thrown when the segment searcher's numeric balanced-tree path receives an expression it cannot translate into a BlockBalancedTreeReader.IntersectVisitor. Only expression types the tree query builder recognizes (e.g. EQ, range comparisons, IN, LIKE prefix) are supported at this code path; anything else reaches the else branch. It wraps the message with the index identifier's log message for context.

Solutions

  1. Check the operator used in the query against the supported operators for numeric SAI indexes (EQ, <, <=, >, >=, IN, LIKE 'prefix%')
  2. Rewrite the query to use a supported operator or allow filtering (ALLOW FILTERING) without the index
  3. Ensure all nodes run the same Cassandra version so query planning and searchers agree
  4. If a valid operator hits this, file a bug with the exact query and index type

Example fix

// before
SELECT ... FROM t WHERE numcol CONTAINS 5;   // unsupported on numeric SAI
// after
SELECT ... FROM t WHERE numcol = 5;          // supported equality intersection
Defensive patterns

Strategy: validation

Validate before calling

Set<Expression.Op> supported = Set.of(EQ, LT, LTE, GT, GTE, IN, LIKE_PREFIX);
if (!supported.contains(exp.getOp()))
    throw new IllegalArgumentException("Operator not supported by numeric SAI index: " + exp.getOp());

Type guard

boolean isNumericIndexOperator(Expression exp) {
    return Expression.IndexOperator.EQ.equals(exp.getIndexOperator())
        || Expression.IndexOperator.RANGE.equals(exp.getIndexOperator());
}

Try / catch

try {
    return searcher.search(exp, ...);
} catch (IllegalArgumentException e) {
    logger.warn("Falling back to non-index scan: {}", e.getMessage());
    return fallbackScan(exp);
}

Prevention

When it happens

Trigger: Executing a query whose expression `exp` is dispatched to the numeric index searcher but is not one of the supported operators, e.g. an operator added in newer code, a null/unsupported operator, or an ANN/CONTAINS expression misrouted here.

Common situations: Querying a numeric SAI index with a new operator before the tree query builder was extended, version skew between coordinator and node code, or internal routing bugs selecting the wrong searcher.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/index/sai/disk/v1/segment/NumericIndexSegmentSearcher.java:96

    {
        return treeReader.memoryUsage();
    }

    @Override
    public KeyRangeIterator search(Expression exp, AbstractBounds<PartitionPosition> keyRange, QueryContext context) throws IOException
    {
        if (logger.isTraceEnabled())
            logger.trace(index.identifier().logMessage("Searching on expression '{}'..."), exp);

        if (exp.getIndexOperator().isEqualityOrRange())
        {
            final BlockBalancedTreeReader.IntersectVisitor query = balancedTreeQueryFrom(exp, treeReader.getBytesPerValue());
            QueryEventListener.BalancedTreeEventListener listener = MulticastQueryEventListeners.of(context, perColumnEventListener);
            return toPrimaryKeyIterator(treeReader.intersect(query, listener, context), context);
        }
        else
        {
            throw new IllegalArgumentException(index.identifier().logMessage("Unsupported expression during index query: " + exp));
        }
    }

    @Override
    public String toString()
    {
        return MoreObjects.toStringHelper(this)
                          .add("index", index)
                          .add("count", treeReader.getPointCount())
                          .add("bytesPerValue", treeReader.getBytesPerValue())
                          .toString();
    }

    @Override
    public void close()
    {
        treeReader.close();
    }

View on GitHub (pinned to 88fd0f6a0e)