apache/cassandra · error · IllegalStateException
No SSTables available for training in table <keyspaceName>.<
Error message
No SSTables available for training in table <keyspaceName>.<tableName> after flush
What it means
When training is triggered without existing SSTables, train() forces a blocking flush and then selects a referenced view of canonical SSTables. If the flush produces no SSTables (nothing to flush), training cannot proceed and IllegalStateException is thrown. A dictionary needs sample data from SSTables to train on.
Source
Thrown at src/java/org/apache/cassandra/db/compression/CompressionDictionaryManager.java:208
checkTrainingFrequency(dictionary, trainingConfig);
// SSTable-based training: sample from existing SSTables
// this is not closed here but in training runnable when finished
// also, if view is empty, and we throw just below because of it then
// there is nothing to "release" so close is not necessary
ColumnFamilyStore.RefViewFragment refViewFragment = columnFamilyStore.selectAndReference(View.selectFunction(SSTableSet.CANONICAL));
if (refViewFragment.sstables.isEmpty())
{
logger.info("No SSTables available for training in table {}.{}, flushing memtable first", keyspaceName, tableName);
columnFamilyStore.forceBlockingFlush(ColumnFamilyStore.FlushReason.USER_FORCED);
refViewFragment = columnFamilyStore.selectAndReference(View.selectFunction(SSTableSet.CANONICAL));
if (refViewFragment.sstables.isEmpty())
{
throw new IllegalStateException("No SSTables available for training in table " + keyspaceName + '.' + tableName + " after flush");
}
}
scheduler.scheduleSSTableBasedTraining(refViewFragment,
compressionParams,
trainingConfig,
this::handleNewDictionary,
force);
}
@Override
public CompositeData getTrainingState()
{
return scheduler.getLastTrainingState().toCompositeData();
}
@Override
public TabularData listCompressionDictionaries()View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Write data to the table and flush (or wait for SSTables to exist) before training.
- Guard the training call: only invoke train() when the table has at least one SSTable (check tablemetrics or SSTableSet.CANONICAL view).
- If training on a test/empty table, populate sample rows first.
- Schedule training only after bulk loads or compactions that leave SSTables behind.
Example fix
// before
manager.train(true, Map.of()); // throws on empty table
// after
if (!columnFamilyStore.getLiveSSTables().isEmpty() || columnFamilyStore.hasUnreclaimedSpace())
manager.train(true, Map.of()); Defensive patterns
Strategy: validation
Validate before calling
if (columnFamilyStore.getLiveSSTables().isEmpty()) throw new IllegalStateException("skip training: no SSTables"); Try / catch
try { manager.train(true, params); } catch (IllegalStateException e) { /* no SSTables: write data or retry later */ } Prevention
- Only train tables that contain data
- Trigger training after bulk loads, not on empty tables
- Check SSTable counts in scheduled training jobs
When it happens
Trigger: Calling train() on a table that has no data in memtables and no existing canonical SSTables: the forceBlockingFlush writes nothing, refViewFragment.sstables is empty, and the error is thrown.
Common situations: Running training on a freshly created/empty table; all data was just compacted away or TTL-expired; calling training immediately after TRUNCATE; automated jobs that train tables on a schedule regardless of data presence.
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
- Table <keyspaceName>.<tableName> does not support dictionary
- The next training or importing can occur only at least after
- Training already in progress for table <keyspaceName>.<table
- Invalid value for %s: %s
- Cannot create CompressionParams for stored parameters
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/90db41e30081b841.
Report an issue: GitHub.