{"record":{"id":"90db41e30081b841","repo":"apache/cassandra","slug":"no-sstables-available-for-training-in-table-keysp","errorCode":null,"errorMessage":"No SSTables available for training in table <keyspaceName>.<tableName> after flush","messagePattern":"No SSTables available for training in table <keyspaceName>\\.<tableName> after flush","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/compression/CompressionDictionaryManager.java","lineNumber":208,"sourceCode":"        checkTrainingFrequency(dictionary, trainingConfig);\n\n        // SSTable-based training: sample from existing SSTables\n\n        // this is not closed here but in training runnable when finished\n        // also, if view is empty, and we throw just below because of it then\n        // there is nothing to \"release\" so close is not necessary\n        ColumnFamilyStore.RefViewFragment refViewFragment = columnFamilyStore.selectAndReference(View.selectFunction(SSTableSet.CANONICAL));\n\n        if (refViewFragment.sstables.isEmpty())\n        {\n            logger.info(\"No SSTables available for training in table {}.{}, flushing memtable first\", keyspaceName, tableName);\n            columnFamilyStore.forceBlockingFlush(ColumnFamilyStore.FlushReason.USER_FORCED);\n\n            refViewFragment = columnFamilyStore.selectAndReference(View.selectFunction(SSTableSet.CANONICAL));\n\n            if (refViewFragment.sstables.isEmpty())\n            {\n                throw new IllegalStateException(\"No SSTables available for training in table \" + keyspaceName + '.' + tableName + \" after flush\");\n            }\n        }\n\n        scheduler.scheduleSSTableBasedTraining(refViewFragment,\n                                               compressionParams,\n                                               trainingConfig,\n                                               this::handleNewDictionary,\n                                               force);\n    }\n\n    @Override\n    public CompositeData getTrainingState()\n    {\n        return scheduler.getLastTrainingState().toCompositeData();\n    }\n\n    @Override\n    public TabularData listCompressionDictionaries()","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/compression/CompressionDictionaryManager.java#L190-L226","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nmanager.train(true, Map.of()); // throws on empty table\n// after\nif (!columnFamilyStore.getLiveSSTables().isEmpty() || columnFamilyStore.hasUnreclaimedSpace())\n    manager.train(true, Map.of());","handlingStrategy":"validation","validationCode":"if (columnFamilyStore.getLiveSSTables().isEmpty()) throw new IllegalStateException(\"skip training: no SSTables\");","typeGuard":null,"tryCatchPattern":"try { manager.train(true, params); } catch (IllegalStateException e) { /* no SSTables: write data or retry later */ }","preventionTips":["Only train tables that contain data","Trigger training after bulk loads, not on empty tables","Check SSTable counts in scheduled training jobs"],"tags":["compression","training","sstable"],"backgroundTag":"empty-result-set","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}