apache/cassandra · error · InvalidRequestException

metadata + " does not support filtering by token or incomple

Error message

metadata + " does not support filtering by token or incomplete partition keys"

What it means

RemoteToLocalVirtualTable only supports lookups by complete, decorated partition keys. When the DataRange's bound is a token (not a DecoratedKey) — meaning the query filtered by token() or an incomplete partition key — collect() throws InvalidRequestException because it cannot reconstruct a NodeId from the bound.

Source

Thrown at src/java/org/apache/cassandra/db/virtual/RemoteToLocalVirtualTable.java:153

            builder.addRegularColumn(cm.name, cm.type, cm.getMask(), cm.getColumnConstraints());
        }
        builder.kind(TableMetadata.Kind.VIRTUAL);
        return builder.build();
    }

    @Override
    protected void collect(PartitionsCollector collector)
    {
        ClusterMetadata cm = ClusterMetadata.current();
        NavigableSet<NodeId> matchingIds = cm.directory.peerIds();
        DataRange dataRange = collector.dataRange();
        AbstractBounds<PartitionPosition> bounds = dataRange.keyRange();
        {
            NodeId start = null;
            if (!bounds.left.isMinimum())
            {
                if (!(bounds.left instanceof DecoratedKey))
                    throw new InvalidRequestException(metadata + " does not support filtering by token or incomplete partition keys");
                start = new NodeId(Int32Type.instance.compose(((DecoratedKey) bounds.left).getKey()));
            }
            NodeId end = null;
            if (!bounds.right.isMinimum())
            {
                if (!(bounds.right instanceof DecoratedKey))
                    throw new InvalidRequestException(metadata + " does not support filtering by token or incomplete partition keys");
                end = new NodeId(Int32Type.instance.compose(((DecoratedKey) bounds.right).getKey()));
            }
            if (start != null && end != null) matchingIds = matchingIds.subSet(start, bounds.isStartInclusive(), end, bounds.isEndInclusive());
            else if (start != null) matchingIds = matchingIds.tailSet(start, bounds.isStartInclusive());
            else if (end != null) matchingIds = matchingIds.headSet(end, bounds.isEndInclusive());
        }
        if (dataRange.isReversed())
            matchingIds = matchingIds.descendingSet();

        RowFilter rowFilter = rebind(local, collector.rowFilter());
        ColumnFilter columnFilter = ColumnFilter.rebindVirtual(collector.columnFilter(), local);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Query with full partition key equality: `WHERE pk_col1 = ... [AND pk_col2 = ...]` covering the entire key.
  2. Avoid token() predicates on this virtual table.
  3. If scanning is required, iterate keys from the source table and query the virtual table per key.

Example fix

// before
SELECT * FROM system_views.remote_to_local WHERE token(id) > -9223372036854775808;
// after
SELECT * FROM system_views.remote_to_local WHERE id = 42;
Defensive patterns

Strategy: validation

Validate before calling

// Require full partition-key equality, no token() predicates
if (cql.contains("token("))
    throw new IllegalArgumentException("token filtering is not supported on remote_to_local virtual tables");
// and ensure all partition key columns have equality restrictions

Try / catch

try { rs = session.execute(query); }
catch (com.datastax.oss.driver.api.core.servererrors.InvalidQueryException e) {
    if (e.getMessage().contains("does not support filtering by token")) { /* rewrite with full-key equality */ }
    else throw e;
}

Prevention

When it happens

Trigger: `SELECT ... FROM <remote_to_local virtual table> WHERE token(id) > X;` or restricting only part of a composite partition key, causing bounds.left/right to be a token bound rather than a DecoratedKey.

Common situations: Token-range paging patterns copied from normal table queries; queries restricting a prefix of a composite partition key; tooling that pages virtual tables by token for parallelism.

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