apache/cassandra · error · InvalidRequestException

%s cannot be used with %s relations

Error message

%s cannot be used with %s relations

What it means

Cassandra validates that the comparison operator used in a relation (WHERE-clause restriction) is supported for the kind of columns expression it is applied to. `Operator.validateFor(ColumnsExpression)` calls `isSupportedByRestrictionsOn`; if the operator is not allowed for that restriction kind (e.g. multi-cell slice comparisons, token, CONTAINS, or LIKE applied where unsupported), it throws naming both the operator and the relation kind.

Source

Thrown at src/java/org/apache/cassandra/cql3/Operator.java:978

    List<ByteBuffer> unpackMultiCellElements(MultiElementType<?> type, ByteBuffer value)
    {
        checkTrue(value != null, "Invalid comparison with null for operator \"%s\"", this);
        List<ByteBuffer> elements = type.unpack(value);
        if (type.isCollection() && elements.isEmpty())
            throw  invalidRequest("Invalid comparison with an empty %s for operator \"%s\"", ((CollectionType<?>) type).kind, this);
        return elements;
    }

    public static int serializedSize()
    {
        return 4;
    }

    public void validateFor(ColumnsExpression expression)
    {
        // this method is used only in restrictions, not in conditions where different rules apply for now
        if (!isSupportedByRestrictionsOn(expression))
            throw invalidRequest("%s cannot be used with %s relations", this, expression);

        switch (expression.kind())
        {
            case SINGLE_COLUMN:
                ColumnMetadata firstColumn = expression.firstColumn();
                AbstractType<?> columnType = firstColumn.type;
                if (isSlice() && this != Operator.NEQ)
                {
                    if (columnType.referencesDuration())
                    {
                        checkFalse(columnType.isCollection(), "Slice restrictions are not supported on collections containing durations");
                        checkFalse(columnType.isTuple(), "Slice restrictions are not supported on tuples containing durations");
                        checkFalse(columnType.isUDT(), "Slice restrictions are not supported on UDTs containing durations");
                        throw invalidRequest("Slice restrictions are not supported on duration columns");
                    }
                }
                else
                {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Rewrite the relation using an operator supported for that column type (e.g. `=` or `IN` for collections, `CONTAINS`/`CONTAINS KEY` only for collections)
  2. Create the required index (e.g. a collection index with `CREATE INDEX ... ON t(ENTRIES(col))`) if the operator requires one
  3. Move the comparison into a client-side filter or into UPDATE ... IF conditions, where different operator rules apply
  4. Change the column to a type that supports the operator (e.g. use a scalar text column with SASI/LIKE support for LIKE queries)

Example fix

// before
SELECT * FROM t WHERE tags > {'a'};  -- slice on set not allowed in restrictions
// after
SELECT * FROM t WHERE tags CONTAINS 'a';
Defensive patterns

Strategy: validation

Validate before calling

// Validate operator applicability before building the relation
Set<Operator> collectionRestrictionOps = EnumSet.of(EQ, IN, CONTAINS, CONTAINS_KEY);
if (isCollectionColumn(col) && !collectionRestrictionOps.contains(op))
    throw new IllegalArgumentException("Operator " + op + " not allowed on collection restriction for " + col);
if (op == LIKE && !(col.getType().unwrap() instanceof TextType))
    throw new IllegalArgumentException("LIKE requires a text column");

Try / catch

try {
    return session.execute(query);
} catch (InvalidRequestException e) {
    if (e.getMessage().contains("cannot be used with")) {
        // fall back to an operator supported by restrictions on this column kind
        return session.execute(rewriteWithSupportedOperator(query));
    }
    throw e;
}

Prevention

When it happens

Trigger: CQL like `WHERE map_col > {..}` in a regular (non-indexed) restriction where slice operators are not permitted; using `CONTAINS`/`CONTAINS KEY` on a non-collection column; using `LIKE` on a non-text column; applying `IN` or slice operators to multi-column relations that don't support them.

Common situations: Querying a collection column with ordering operators without a suitable index (frozen + secondary index); expecting Map/List/Set ordering semantics in WHERE clauses; conditions written for conditions-column (JSON/UPDATE IF) syntax reused in SELECT restrictions where rules differ.

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