apache/cassandra · error · RuntimeException

Failed adding SSTables

Error message

Failed adding SSTables

What it means

After verification and moving, SSTableImporter adds the new SSTableReaders to the ColumnFamilyStore; any Throwable during that leveling step (cache load, lifecycle registration, metadata update) is logged and rethrown as RuntimeException 'Failed adding SSTables', rolling back by invalidating caches for the affected readers.

Source

Thrown at src/java/org/apache/cassandra/db/SSTableImporter.java:241

        try (Refs<SSTableReader> refs = Refs.ref(newSSTables))
        {
            abortIfDraining();

            // Validate existing SSTable-attached indexes, and then build any that are missing:
            if (!cfs.indexManager.validateSSTableAttachedIndexes(newSSTables, false, options.validateIndexChecksum))
                cfs.indexManager.buildSSTableAttachedIndexesBlocking(newSSTables);

            cfs.getTracker().addSSTables(newSSTables);
            for (SSTableReader reader : newSSTables)
            {
                if (options.invalidateCaches && cfs.isRowCacheEnabled())
                    invalidateCachesForSSTable(reader);
            }
        }
        catch (Throwable t)
        {
            logger.error("[{}] Failed adding SSTables", importID, t);
            throw new RuntimeException("Failed adding SSTables", t);
        }

        logger.info("[{}] Done loading load new SSTables for {}/{}", importID, cfs.getKeyspaceName(), cfs.getTableName());
        return failedDirectories;
    }

    /**
     * Check the state of this node and throws an {@link InterruptedException} if it is currently draining
     *
     * @throws InterruptedException if the node is draining
     */
    private static void abortIfDraining() throws InterruptedException
    {
        if (StorageService.instance.isDraining())
            throw new InterruptedException("SSTables import has been aborted");
    }

    private void logLeveling(UUID importID, Set<SSTableReader> newSSTables)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Inspect the wrapped cause 't' in the log to fix the root problem (memory, I/O, corrupt component)
  2. Clean up partially added SSTables: restart the node so its SSTable list is rebuilt, verify with nodetool cfstats, and re-import
  3. Import in smaller batches to limit cache/memory pressure
  4. Pause concurrent operations (compactions, repairs) on the table during import

Example fix

// before: one huge import
nodetool import -- ks table /data/import  # 2TB of sstables, OOM in addSSTables
// after: batched import
for d in /data/import/batch-*; do nodetool import -- ks table "$d"; done
Defensive patterns

Strategy: try-catch

Try / catch

try {
    nodetool("import", "--", ks, table, dir);
} catch (RuntimeException e) {
    logger.error("Import failed adding SSTables; restarting node to rebuild SSTable list", e);
    restartNode();
    verifyWithCfstats(ks, table);
}

Prevention

When it happens

Trigger: importNewSSTables finishes moving SSTables and calls cfs.addSSTables / logLeveling; registration into the live SSTable set fails (I/O error updating metadata, cache failure, out of memory, unexpected reader state).

Common situations: Insufficient heap/off-heap memory for key/value caches on large imports; concurrent compaction or lifecycle operations colliding with the import; corrupted index components that pass file checks but fail on reader open.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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