apache/cassandra · warning · RuntimeException

Cleanup of the system keyspace is neither necessary nor wise

Error message

Cleanup of the system keyspace is neither necessary nor wise

What it means

forceKeyspaceCleanup on the system keyspace is rejected because the system keyspace's data must never be compacted away — cleanup removes data not owned by this node, and system tables (auth, local, peers, etc.) are always locally owned and required for operation. Thrown as RuntimeException to make the misuse obvious.

Source

Thrown at src/java/org/apache/cassandra/service/StorageService.java:2712

    public String getSavedCachesLocation()
    {
        return FileUtils.getCanonicalPath(DatabaseDescriptor.getSavedCachesLocation());
    }

    public int getCurrentGenerationNumber()
    {
        return Gossiper.instance.getCurrentGenerationNumber(getBroadcastAddressAndPort());
    }

    public int forceKeyspaceCleanup(String keyspaceName, String... tables) throws IOException, ExecutionException, InterruptedException
    {
        return forceKeyspaceCleanup(0, keyspaceName, tables);
    }

    public int forceKeyspaceCleanup(int jobs, String keyspaceName, String... tableNames) throws IOException, ExecutionException, InterruptedException
    {
        if (isLocalSystemKeyspace(keyspaceName))
            throw new RuntimeException("Cleanup of the system keyspace is neither necessary nor wise");

        CompactionManager.AllSSTableOpStatus status = CompactionManager.AllSSTableOpStatus.SUCCESSFUL;
        logger.info("Starting {} on {}.{}", OperationType.CLEANUP, keyspaceName, Arrays.toString(tableNames));
        for (ColumnFamilyStore cfStore : getValidColumnFamilies(false, false, keyspaceName, tableNames))
        {
            CompactionManager.AllSSTableOpStatus oneStatus = cfStore.forceCleanup(jobs);
            if (oneStatus != CompactionManager.AllSSTableOpStatus.SUCCESSFUL)
                status = oneStatus;
        }
        logger.info("Completed {} with status {}", OperationType.CLEANUP, status);
        return status.statusCode;
    }

    public int scrub(boolean disableSnapshot, boolean skipCorrupted, boolean checkData, boolean reinsertOverflowedTTL, int jobs, String keyspaceName, String... tableNames) throws IOException, ExecutionException, InterruptedException
    {
        IScrubber.Options options = IScrubber.options()
                                             .skipCorrupted(skipCorrupted)
                                             .checkData(checkData)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Exclude the 'system' keyspace from your cleanup loop or command
  2. Only run cleanup on user keyspaces and system_auth/system_distributed/system_traces if needed
  3. If disk space in system tables is the concern, investigate table-specific issues instead of cleanup

Example fix

// before
for (String ks : keyspaces) storageService.forceKeyspaceCleanup(0, ks);
// after
for (String ks : keyspaces)
    if (!ks.equals("system")) storageService.forceKeyspaceCleanup(0, ks);
Defensive patterns

Strategy: validation

Validate before calling

if (keyspace.equals("system"))
    skipCleanup(keyspace); // never cleanup the system keyspace

Try / catch

try { ss.forceKeyspaceCleanup(0, ks); } catch (RuntimeException e) { log.warn("skipped {}: {}", ks, e.getMessage()); }

Prevention

When it happens

Trigger: Running `nodetool cleanup` against the 'system' keyspace, or calling StorageServiceMBean.forceKeyspaceCleanup / forceKeyspaceCleanup(int, String, String...) with keyspaceName='system'.

Common situations: Operators running cleanup across all keyspaces by scripting per-keyspace calls without excluding 'system'; confusion between 'system' and 'system_auth'/'system_distributed' (the latter are cleanable).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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