apache/cassandra · warning

Aggregation query used on multiple partition keys (IN…

Error message

Aggregation query used on multiple partition keys (IN restriction)

What it means

Aggregation with an IN restriction on the partition key aggregates across multiple partitions in one coordinator operation. Cassandra warns the client because cost grows linearly with the number of partition keys in the IN list.

Solutions

  1. Issue one aggregation query per partition key and sum client-side
  2. Reduce the IN list size or fan out queries in parallel
  3. Precompute counts with counters or an aggregate table
  4. Use analytics tooling for multi-partition aggregation

Example fix

// before
SELECT count(*) FROM sensor_data WHERE device_id IN (1,2,3,4,5);
// after
SELECT count(*) FROM sensor_data WHERE device_id = 1; // repeat per device, sum client-side
Defensive patterns

Strategy: validation

Validate before calling

if (isAggregate(cql) && cql.matches(".*IN\\s*\\(.*")) {
    throw new IllegalArgumentException("aggregate with IN on partition key not allowed; fan out per key");
}

Prevention

When it happens

Trigger: `SELECT count(*) FROM ks.tbl WHERE pk IN (k1, k2, ..., kN)` with N > 1; SelectStatement.execute detects restrictions.keyIsInRelation() for an aggregating query and warns.

Common situations: Dashboard queries counting across a handful of known partitions; batch report jobs issuing large IN lists; gradual growth of IN lists until scans become slow.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/SelectStatement.java:627

                                       long nowInSec,
                                       int userLimit,
                                       AggregationSpecification aggregationSpec,
                                       Dispatcher.RequestTime requestTime,
                                       boolean unmask)
    {
        Guardrails.pageSize.guard(pageSize, table(), false, state.getClientState());

        if (aggregationSpecFactory != null)
        {
            if (!restrictions.hasPartitionKeyRestrictions())
            {
                warn("Aggregation query used without partition key");
                noSpamLogger.warn(String.format("Aggregation query used without partition key on table %s.%s, aggregation type: %s",
                                                 keyspace(), table(), aggregationSpec.kind()));
            }
            else if (restrictions.keyIsInRelation())
            {
                warn("Aggregation query used on multiple partition keys (IN restriction)");
                noSpamLogger.warn(String.format("Aggregation query used on multiple partition keys (IN restriction) on table %s.%s, aggregation type: %s",
                                                 keyspace(), table(), aggregationSpec.kind()));
            }
        }

        // We can't properly do post-query ordering if we page (see #6722)
        // For GROUP BY or aggregation queries we always page internally even if the user has turned paging off
        checkFalse(pageSize > 0 && needsPostQueryOrdering(),
                  "Cannot page queries with both ORDER BY and a IN restriction on the partition key;"
                  + " you must either remove the ORDER BY or the IN and sort client side, or disable paging for this query");

        ResultMessage.Rows msg;
        try (PartitionIterator page = pager.fetchPage(pageSize, requestTime))
        {
            msg = processResults(page, options, selectors, nowInSec, userLimit, aggregationSpec, unmask, state.getClientState());
        }

        // Please note that the isExhausted state of the pager only gets updated when we've closed the page, so this

View on GitHub (pinned to 88fd0f6a0e)