apache/cassandra · error · UnsupportedOperationException

prefix queries in CONTAINS mode are not supported by this…

Error message

prefix queries in CONTAINS mode are not supported by this index

What it means

OnDiskIndex.search rejects PREFIX expressions when the index was built in CONTAINS mode without marked partials: CONTAINS-mode SASI indexes only store suffix matches, so a prefix (LIKE 'foo%') query cannot be answered. Throws UnsupportedOperationException.

Solutions

  1. Rewrite the query as a suffix/substring match (LIKE '%abc%') in CONTAINS mode
  2. Rebuild the index in PREFIX mode if prefix queries are needed
  3. Use CONTAINS mode index built with support for marked partials so prefix queries are answerable

Example fix

// before
SELECT * FROM t WHERE col LIKE 'foo%';  // CONTAINS-mode SASI index
// after
SELECT * FROM t WHERE col LIKE '%foo%';  // or rebuild index in PREFIX mode
Defensive patterns

Strategy: try-catch

Validate before calling

boolean isPrefixQuery(String likePattern) { return !likePattern.startsWith("%") && likePattern.endsWith("%"); }
// reject prefix patterns when the column's SASI index is mode=CONTAINS

Try / catch

try { rs = session.execute(query); } catch (UnsupportedOperationException e) { if (e.getMessage().contains("prefix queries in CONTAINS mode")) { rs = runAlternativeQuery(suffixPattern); } else throw e; }

Prevention

When it happens

Trigger: Executing a LIKE 'abc%' (prefix) query against a column indexed with mode=CONTAINS when the on-disk index lacks marked partial terms (hasMarkedPartials == false).

Common situations: Application assumes CONTAINS mode supports all LIKE patterns; schema evolved so index built without support for partial prefix terms; tests (testStringSAConstruction, rows, etc.) exercise prefix queries against CONTAINS indexes.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/index/sasi/disk/OnDiskIndex.java:229

    public DataTerm max()
    {
        DataBlock block = dataLevel.getBlock(dataLevel.blockCount - 1);
        return block.getTerm(block.termCount() - 1);
    }

    /**
     * Search for rows which match all of the terms inside the given expression in the index file.
     *
     * @param exp The expression to use for the query.
     *
     * @return Iterator which contains rows for all of the terms from the given range.
     */
    public RangeIterator<Long, Token> search(Expression exp)
    {
        assert mode.supports(exp.getOp());

        if (exp.getOp() == Expression.Op.PREFIX && mode == OnDiskIndexBuilder.Mode.CONTAINS && !hasMarkedPartials)
            throw new UnsupportedOperationException("prefix queries in CONTAINS mode are not supported by this index");

        // optimization in case single term is requested from index
        // we don't really need to build additional union iterator
        if (exp.getOp() == Op.EQ)
        {
            DataTerm term = getTerm(exp.lower.value);
            return term == null ? null : term.getTokens();
        }

        // convert single NOT_EQ to range with exclusion
        final Expression expression = (exp.getOp() != Op.NOT_EQ)
                                        ? exp
                                        : new Expression(exp).setOp(Op.RANGE)
                                                .setLower(new Expression.Bound(minTerm, true))
                                                .setUpper(new Expression.Bound(maxTerm, true))
                                                .addExclusion(exp.lower.value);

        List<ByteBuffer> exclusions = new ArrayList<>(expression.exclusions.size());

View on GitHub (pinned to 88fd0f6a0e)