apache/cassandra · warning · SkipRepairException

Empty keyspace, skipping repair

Error message

%s Empty keyspace, skipping repair: %s

What it means

Before coordinating a repair, getColumnFamilies resolves the requested tables; if none of them exist or are valid in the keyspace, the repair is aborted via SkipRepairException with the message 'Empty keyspace, skipping repair'. This is an intentional skip, not a fault — the coordinator just has nothing to do.

Solutions

  1. Check the keyspace/table names in the repair request with DESC KEYSPACE / nodetool cfstats and correct typos.
  2. Drop explicit table names to repair the whole keyspace, or skip the call when the keyspace is empty.
  3. In automation, catch SkipRepairException (it signals 'nothing to do') and treat it as a no-op.

Example fix

// before
StorageService.instance.repairAsync(ks, optionsWithTables("old_table"));
// after
if (keyspaceHasTables(ks, "old_table")) StorageService.instance.repairAsync(ks, optionsWithTables("old_table"));
Defensive patterns

Strategy: try-catch

Validate before calling

boolean tablesExist = requestedTables.stream().allMatch(t -> Schema.instance.getCFMetaData(ks, t) != null);

Try / catch

try { repairAsync(ks, opts); } catch (SkipRepairException e) { logger.info("Repair skipped: {}", e.getMessage()); } // expected no-op

Prevention

When it happens

Trigger: Invoking repair with a column-family list whose members all fail validColumnFamilies (typo'd or dropped tables), or repairing a keyspace with no surviving tables.

Common situations: Scripts referencing tables deleted by schema changes; case-sensitive table-name mistakes; repairing a keyspace before any tables are created.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/repair/RepairCoordinator.java:361

                {
                    fail(null);
                }
                else
                {
                    success(pair.right.get());
                    ctx.repair().cleanUp(state.id, neighborsAndRanges.participants);
                }
            }
        });
    }

    private List<ColumnFamilyStore> getColumnFamilies()
    {
        String[] columnFamilies = state.options.getColumnFamilies().toArray(new String[state.options.getColumnFamilies().size()]);
        Iterable<ColumnFamilyStore> validColumnFamilies = this.validColumnFamilies.apply(state.keyspace, columnFamilies);

        if (Iterables.isEmpty(validColumnFamilies))
            throw new SkipRepairException(String.format("%s Empty keyspace, skipping repair: %s", state.id, state.keyspace));
        return Lists.newArrayList(validColumnFamilies);
    }

    private TraceState maybeCreateTraceState(Iterable<ColumnFamilyStore> columnFamilyStores)
    {
        if (!state.options.isTraced())
            return null;

        StringBuilder cfsb = new StringBuilder();
        for (ColumnFamilyStore cfs : columnFamilyStores)
            cfsb.append(", ").append(cfs.getKeyspaceName()).append(".").append(cfs.name);

        TimeUUID sessionId = Tracing.instance.newSession(Tracing.TraceType.REPAIR);
        TraceState traceState = Tracing.instance.begin("repair", ImmutableMap.of("keyspace", state.keyspace, "columnFamilies",
                                                                                 cfsb.substring(2)));
        traceState.enableActivityNotification(tag);
        for (ProgressListener listener : listeners)
            traceState.addProgressListener(listener);

View on GitHub (pinned to 88fd0f6a0e)