apache/cassandra · error · InvalidRequestException

Must specify full partition key bounds for the underlying ta

Error message

Must specify full partition key bounds for the underlying table

What it means

rebind() translates the virtual table's clustering bounds into a row filter on the underlying remote table. If the partition key bounds on the underlying table are partial (greater than 0 but fewer columns than the full partition key) and implicit ALLOW FILTERING is not enabled, the translation cannot produce an efficient scan and throws InvalidRequestException.

Source

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

        for (RowFilter.Expression in : rowFilter.getExpressions())
        {
            RowFilter.Expression out = in.rebind(local);
            if (out != null)
                result.add(out);
        }
        return result;
    }

    private List<Request> rebind(TableMetadata local, Slice slice, boolean reversed, RowFilter rowFilter, ColumnFilter columnFilter)
    {
        ClusteringBound<?> start = slice.start();
        ClusteringBound<?> end = slice.end();
        int pkCount = local.partitionKeyColumns().size();
        // TODO (expected): we can filter by partition key by inserting a new row filter, but need to impose ALLOW FILTERING restrictions
        if (((start.size() > 0 && start.size() < pkCount) || (end.size() > 0 && end.size() < pkCount)))
        {
            if (!allowFilteringLocalPartitionKeysImplicitly)
                throw new InvalidRequestException("Must specify full partition key bounds for the underlying table");

            List<ColumnMetadata> pks = local.partitionKeyColumns();
            ByteBuffer[] starts = start.getBufferArray();
            ByteBuffer[] ends = end.getBufferArray();

            int minCount = Math.min(start.size(), end.size());
            int maxCount = Math.max(start.size(), end.size());
            int commonPrefixLength = 0;
            while (commonPrefixLength < minCount && equalPart(start, end, commonPrefixLength))
                ++commonPrefixLength;

            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]);
            }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Restrict on ALL partition key columns of the underlying table (full equality/range on every PK column).
  2. Remove the partial PK restriction and filter client-side after fetching.
  3. Enable the internal flag allowFilteringLocalPartitionKeysImplicitly if this usage is intended and acceptable performance-wise.
  4. Add ALLOW FILTERING semantics at the base-table level if querying the underlying table directly.

Example fix

// before
SELECT * FROM vt WHERE pk_col1 = 'a';  -- pk has 2 columns
// after
SELECT * FROM vt WHERE pk_col1 = 'a' AND pk_col2 = 42;
Defensive patterns

Strategy: validation

Validate before calling

// Ensure all partition key columns of the underlying table are restricted
int pkCount = underlyingTable.partitionKeyColumns().size();
if (restrictedPkColumns.size() > 0 && restrictedPkColumns.size() < pkCount)
    throw new IllegalArgumentException("Must restrict all " + pkCount + " partition key columns");

Try / catch

try { session.execute(query); }
catch (InvalidRequestException e) {
    if (e.getMessage().contains("full partition key bounds"))
        // rewrite query with complete PK restriction or filter client-side
}

Prevention

When it happens

Trigger: SELECT that restricts only some columns of the underlying table's partition key within the WHERE clause (start.size() > 0 && < pkCount, or same for end) while the remote translation does not permit partial PK filtering.

Common situations: Queries ported from the base table where partial partition key restrictions plus ALLOW FILTERING were allowed; multi-column partition keys in the underlying table restricted on only the first column.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/b8de0ffc784351a8. Report an issue: GitHub.