apache/cassandra · error · InvalidRequestException

Operator %s not supported for txn_id

Error message

Operator %s not supported for txn_id

What it means

AbstractLazyVirtualTable's filtering logic translates CQL row-filter expressions into range bounds over a backing map of lazily-computed rows. Only EQ, LTE, LT, GTE and GT are translatable; any other operator (e.g. NEQ, IN, LIKE, CONTAINS) applied to the filtered column cannot be pushed down and throws InvalidRequestException.

Source

Thrown at src/java/org/apache/cassandra/db/virtual/AbstractLazyVirtualTable.java:313

                }
            };
        }

        @Override
        @Nullable
        public <I, O> FilterRange<O> filters(String columnName, Function<I, O> translate, UnaryOperator<O> exclusiveStart, UnaryOperator<O> exclusiveEnd)
        {
            ColumnMetadata column = columnLookup.get(columnName);
            O min = null, max = null;
            for (RowFilter.Expression expression : rowFilter().getExpressions())
            {
                if (!expression.column().equals(column))
                    continue;

                O bound = translate.apply((I)column.type.compose(expression.getIndexValue()));
                switch (expression.operator())
                {
                    default: throw new InvalidRequestException("Operator " + expression.operator() + " not supported for txn_id");
                    case EQ:  min = max = bound; break;
                    case LTE: max = bound; break;
                    case LT:  max = exclusiveEnd.apply(bound); break;
                    case GTE: min = bound; break;
                    case GT:  min = exclusiveStart.apply(bound); break;
                }
            }

            return new FilterRange<>(min, max);
        }

        @Override
        public RowCollector row(Object... primaryKeys)
        {
            int pkSize = metadata.partitionKeyColumns().size();
            int ckSize = metadata.clusteringColumns().size();
            if (pkSize + ckSize != primaryKeys.length)
                throw new IllegalArgumentException();

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Rewrite the query to use only EQ/LT/LTE/GT/GT operators on the column (e.g. express `!=` as two range queries or filter client-side)
  2. Filter unsupported predicates in application code after fetching rows without that predicate
  3. Use `system_views` equivalent real tables or full-table scans plus client filtering if precise ranges are not needed

Example fix

// before
SELECT * FROM system_views.transactions_in_progress WHERE txn_id != 'abc';
// after
SELECT * FROM system_views.transactions_in_progress WHERE txn_id > 'aaa' AND txn_id < 'abc';
SELECT * FROM system_views.transactions_in_progress WHERE txn_id > 'abc';
// then filter result rows client-side
Defensive patterns

Strategy: validation

Validate before calling

// only EQ/LT/LTE/GT/GTE are pushable
Set<String> ok = Set.of("EQ","LT","LTE","GT","GTE");
if (!ok.contains(operator)) filterClientSide();

Try / catch

try { execute(cql); } catch (InvalidRequestException e) { if (e.getMessage().contains("not supported for txn_id")) fallbackScanAndFilter(); else throw e; }

Prevention

When it happens

Trigger: Querying a virtual table (e.g. system_views.transactions_in_progress style tables) with a WHERE clause using an unsupported operator on the filterable key column, such as `WHERE txn_id != x`, `txn_id IN (...)`, or `txn_id CONTAINS ...`.

Common situations: Developers probing virtual tables with generic predicates assuming full SQL semantics; ORMs or dashboards generating NEQ/IN filters automatically; cqlsh exploratory queries.

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