apache/cassandra · error · InvalidRequestException

This table currently does not support the complex partial pa

Error message

This table currently does not support the complex partial partition key filters implied for the underlying table

What it means

Even with partial PK bounds allowed, rebind() can only handle simple cases where start/end bounds share a common prefix and can be lowered into row-filter expressions. Complex interleaved or mismatched partial bounds (e.g. start specifies col1+col2, end only col1 with differing tails) cannot be expressed as a row filter, so it throws InvalidRequestException.

Source

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

            RowFilter commonRowFilter = rowFilter;
            if (commonPrefixLength > 0)
            {
                commonRowFilter = copy(commonRowFilter);
                for (int i = 0 ; i < commonPrefixLength ; ++i)
                    commonRowFilter.add(pks.get(i), Operator.EQ, starts[i]);
            }

            Operator lastStartOp = start.isInclusive() ? Operator.GTE : Operator.GT;
            Operator lastEndOp = end.isInclusive() ? Operator.LTE : Operator.LT;
            if (commonPrefixLength == Math.max(minCount, maxCount - 1))
            {
                // can simply add our remaining filters and continue on our way
                addExpressions(commonRowFilter, pks, commonPrefixLength, starts, Operator.GTE, lastStartOp);
                addExpressions(commonRowFilter, pks, commonPrefixLength, ends, Operator.LTE, lastEndOp);
                return List.of(new Request(DataRange.allData(local.partitioner), commonRowFilter, columnFilter));
            }

            throw new InvalidRequestException("This table currently does not support the complex partial partition key filters implied for the underlying table");
        }

        ByteBuffer[] startBuffers = start.getBufferArray();
        PartitionPosition startBound;
        if (start.size() == 0) startBound = local.partitioner.getMinimumToken().minKeyBound();
        else if (pkCount == 1) startBound = local.partitioner.decorateKey(startBuffers[0]);
        else startBound = local.partitioner.decorateKey(CompositeType.build(ByteBufferAccessor.instance, Arrays.copyOf(startBuffers, pkCount)));

        ByteBuffer[] endBuffers = end.getBufferArray();
        PartitionPosition endBound;
        if (end.size() == 0) endBound = local.partitioner.getMinimumToken().maxKeyBound();
        else if (pkCount == 1) endBound = local.partitioner.decorateKey(endBuffers[0]);
        else endBound = local.partitioner.decorateKey(CompositeType.build(ByteBufferAccessor.instance, Arrays.copyOf(endBuffers, pkCount)));

        AbstractBounds<PartitionPosition> bounds = AbstractBounds.bounds(startBound, start.isEmpty() || start.size() > pkCount || start.isInclusive(),
                                                                         endBound, end.isEmpty() || end.size() > pkCount || end.isInclusive());
        boolean hasSlices = start.size() > pkCount || end.size() > pkCount;
        if (!hasSlices)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Make both bounds specify the same, full set of partition key columns.
  2. Simplify the query to equality on the partition key so a single remote read partition is produced.
  3. Split the query into several fully-bounded queries covering the desired range.
  4. Filter the extra dimension client-side after fetching full partitions.

Example fix

// before
SELECT * FROM vt WHERE pk1 > 'a';              -- only one bound, partial
// after
SELECT * FROM vt WHERE pk1 >= 'a' AND pk1 <= 'b' AND pk2 >= 0 AND pk2 <= 999;
Defensive patterns

Strategy: validation

Validate before calling

// Reject mismatched partial bounds up front
if (startCols != endCols || (startCols > 0 && startCols < pkCount))
    throw new IllegalArgumentException("Use equal, full partition key bounds on both sides");

Try / catch

try { session.execute(query); }
catch (InvalidRequestException e) {
    if (e.getMessage().contains("complex partial partition key filters"))
        // split into fully-bounded queries
}

Prevention

When it happens

Trigger: Partial partition key bounds on the underlying table where the start and end bounds have incompatible shapes beyond the common prefix — detected after commonPrefixLength computation when neither the full-prefix nor simple cases apply.

Common situations: Range queries over a composite partition key where each bound restricts a different number of PK columns; tooling generating arbitrary clustering/pk bounds; mixed inclusive/exclusive bounds on partial keys.

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