apache/cassandra · warning

Attempting to load denylist and not enough nodes are availab

Error message

Attempting to load denylist and not enough nodes are available for a {} refresh. Reload the denylist when unavailable nodes are recovered to ensure your denylist remains in sync.

What it means

PartitionDenylist.checkDenylistNodeAvailability logs this warning when there are not enough live nodes to satisfy the configured denylist consistency level for a SELECT * over the denylist table. It returns the insufficiency (false) to callers, meaning the denylist cannot be refreshed at this time.

Source

Thrown at src/java/org/apache/cassandra/schema/PartitionDenylist.java:181

        int retryInSeconds = DatabaseDescriptor.getDenylistInitialLoadRetrySeconds();
        logger.info("{} while loading partition denylist cache. Scheduled retry in {} seconds.", retryReason, retryInSeconds);
        ScheduledExecutors.optionalTasks.schedule(this::initialLoad, retryInSeconds, TimeUnit.SECONDS);
    }

    private boolean checkDenylistNodeAvailability()
    {
        TableMetadata denyListTable = ClusterMetadata.current().schema.getKeyspaceMetadata(SystemDistributedKeyspace.NAME)
                                                              .getTableOrViewNullable(SystemDistributedKeyspace.PARTITION_DENYLIST_TABLE);
        if (denyListTable == null)
        {
            logger.warn("Partition denylist table metadata not found");
            return false;
        }

        boolean sufficientNodes = RangeCommands.sufficientLiveNodesForSelectStar(denyListTable, DatabaseDescriptor.getDenylistConsistencyLevel());
        if (!sufficientNodes)
        {
            AVAILABILITY_LOGGER.warn("Attempting to load denylist and not enough nodes are available for a {} refresh. Reload the denylist when unavailable nodes are recovered to ensure your denylist remains in sync.",
                                     DatabaseDescriptor.getDenylistConsistencyLevel());
        }
        return sufficientNodes;
    }

    /** Helper method as we need to both build cache on initial init but also on reload of cache contents and params */
    private LoadingCache<TableId, DenylistEntry> buildEmptyCache()
    {
        // We rely on details of .refreshAfterWrite to reload this async in the background when it's hit:
        // https://github.com/ben-manes/caffeine/wiki/Refresh
        return Caffeine.newBuilder()
                       .refreshAfterWrite(DatabaseDescriptor.getDenylistRefreshSeconds(), TimeUnit.SECONDS)
                       .executor(executor)
                       .build(new CacheLoader<TableId, DenylistEntry>()
                       {
                           @Override
                           public DenylistEntry load(final TableId tid)
                           {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Recover/restart the unavailable nodes, then reload the denylist as the message advises
  2. Lower cassandra.denylist_consistency_level (e.g. from QUORUM to LOCAL_QUORUM or ONE) if the current level exceeds cluster capacity
  3. Run nodetool status to identify and fix down nodes / replication gaps
  4. Re-trigger denylist reload (nodetool reload PartitionDenylist / restart) after capacity returns

Example fix

// before
cassandra.denylist_consistency_level: EACH_QUORUM  # requires all DCs healthy
// after
cassandra.denylist_consistency_level: LOCAL_QUORUM # tolerant of remote-DC outage
Defensive patterns

Strategy: fallback

Validate before calling

boolean canRefresh = RangeCommands.sufficientLiveNodesForSelectStar(
    denyListTable, DatabaseDescriptor.getDenylistConsistencyLevel());
if (!canRefresh) {
    logger.warn("Deferring denylist refresh; will retry when nodes recover");
    scheduleDenylistRetry();
}

Try / catch

// method returns false when nodes insufficient; handle explicitly
if (!denylist.checkDenylistNodeAvailability()) {
    // serve stale denylist from cache until nodes recover
    return;
}

Prevention

When it happens

Trigger: Denylist load/reload/refresh attempted while live node count is below RangeCommands.sufficientLiveNodesForSelectStar for DatabaseDescriptor.getDenylistConsistencyLevel() (e.g. QUORUM with nodes down).

Common situations: Nodes down or decommissioned during denylist refresh; clusters operating at reduced capacity after outages; overly strong denylist_consistency_level relative to cluster size (e.g. EACH_QUORUM in a multi-DC setup).

Related errors


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