apache/cassandra · error · InvalidRequestException

Attempted to read a range containing

Error message

Attempted to read a range containing %d denylisted keys in %s/%s. Range read: %s

What it means

InvalidRequestException thrown when a range/scan read would return keys that are on the partition denylist. partitionDenylist.getDeniedKeysInRangeCount() is checked before RangeCommands.partitions() and any count > 0 rejects the whole range read.

Solutions

  1. Check the loggable token list in the exception to identify the denylisted keys in the scanned range.
  2. Remove denylisted entries if they are no longer meant to block reads.
  3. Restrict the scan to sub-ranges that avoid denylisted keys, or query per-partition instead.
  4. Review log for `readsRejected`/`rangeReadsRejected` denylist metrics to scope which ranges are affected.

Example fix

// before
ResultSet rs = session.execute("SELECT * FROM ks.tbl");
// after
// scan in bounded token sub-ranges that exclude denylisted keys
ResultSet rs = session.execute("SELECT * FROM ks.tbl WHERE token(pk) > ? AND token(pk) <= ?", lo, hi);
Defensive patterns

Strategy: validation

Validate before calling

int denied = (int) jmxConn.invoke(denylistMbean, "getDeniedKeysInRangeCount",
        new Object[]{keyspace, table, loToken, hiToken},
        new String[]{"java.lang.String","java.lang.String","java.lang.String","java.lang.String"});
if (denied > 0) narrowOrAbortScan(loToken, hiToken);

Try / catch

catch (InvalidRequestException e) {
    if (e.getMessage().contains("denylisted keys")) {
        String range = extractLoggedTokens(e.getMessage());
        return scanSubRangesExcluding(range);
    }
    throw e;
}

Prevention

When it happens

Trigger: Any range scan / secondary-index query / partition range query (e.g., SELECT without key restriction, nodetool scan) over a table whose token range contains at least one denylisted partition key.

Common situations: Analytics or repair-style scans running after an operator denylisted keys in the same token range; full-table scans on tables that had denylisted keys added during an incident.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/service/StorageProxy.java:2835

        public String description()
        {
            return command.toCQLString();
        }
    }

    public static PartitionIterator getRangeSlice(PartitionRangeReadCommand command,
                                                  ConsistencyLevel consistencyLevel,
                                                  ReadCoordinator readCoordinator,
                                                  Dispatcher.RequestTime requestTime)
    {
        if (DatabaseDescriptor.getPartitionDenylistEnabled() && DatabaseDescriptor.getDenylistRangeReadsEnabled())
        {
            final int denylisted = partitionDenylist.getDeniedKeysInRangeCount(command.metadata().id, command.dataRange().keyRange());
            if (denylisted > 0)
            {
                denylistMetrics.incrementRangeReadsRejected();
                String tokens = command.loggableTokens();
                throw new InvalidRequestException(String.format("Attempted to read a range containing %d denylisted keys in %s/%s." +
                                                                " Range read: %s", denylisted, command.metadata().keyspace, command.metadata().name,
                                                                tokens));
            }
        }
        return RangeCommands.partitions(command, consistencyLevel, readCoordinator, requestTime);
    }

    public Map<String, List<String>> getSchemaVersions()
    {
        return describeSchemaVersions(false);
    }

    public Map<String, List<String>> getSchemaVersionsWithPort()
    {
        return describeSchemaVersions(true);
    }

    /**

View on GitHub (pinned to 88fd0f6a0e)