{"record":{"id":"98bba329c36a409f","repo":"apache/cassandra","slug":"missing-sai-index-to-import-for-index-s-on-s-s","errorCode":null,"errorMessage":"Missing SAI index to import for index %s on %s.%s","messagePattern":"Missing SAI index to import for index (.+?) on (.+?)\\.(.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/SSTableImporter.java","lineNumber":128,"sourceCode":"                                {\n                                    IndexDescriptor indexDescriptor = IndexDescriptor.create(descriptor,\n                                                                                             cfs.getPartitioner(),\n                                                                                             cfs.metadata().comparator);\n\n                                    String keyspace = cfs.getKeyspaceName();\n                                    String table = cfs.getTableName();\n\n                                    if (!indexDescriptor.isPerSSTableIndexBuildComplete())\n                                        throw new IllegalStateException(String.format(\"Missing SAI index to import for SSTable %s on %s.%s\",\n                                                                                      indexDescriptor.sstableDescriptor.toString(),\n                                                                                      keyspace,\n                                                                                      table));\n\n                                    for (Index index : saiIndexGroup.getIndexes())\n                                    {\n                                        IndexIdentifier indexIdentifier = new IndexIdentifier(keyspace, table, index.getIndexMetadata().name);\n                                        if (!indexDescriptor.isPerColumnIndexBuildComplete(indexIdentifier))\n                                            throw new IllegalStateException(String.format(\"Missing SAI index to import for index %s on %s.%s\",\n                                                                                          index.getIndexMetadata().name,\n                                                                                          keyspace,\n                                                                                          table));\n                                    }\n                                }\n                            }\n\n                            if (options.verifySSTables || options.verifyTokens)\n                                verifySSTableForImport(descriptor, entry.getValue(), options.verifyTokens, options.verifySSTables, options.extendedVerify);\n                        }\n                        catch (Throwable t)\n                        {\n                            if (dir != null)\n                            {\n                                logger.error(\"[{}] Failed verifying SSTable {} in directory {}\", importID, descriptor, dir, t);\n                                failedDirectories.add(dir);\n                            }\n                            else","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/SSTableImporter.java#L110-L146","documentation":"During SSTable import, SSTableImporter verifies that each SAI per-column index registered on the table has finished building for this SSTable (isPerSSTableIndexBuildComplete per IndexIdentifier). If any per-column index build is incomplete it throws IllegalStateException naming the index, keyspace, and table.","triggerScenarios":"importNewSSTables iterates saiIndexGroup.getIndexes(); for one index the SSTable's descriptor reports isPerColumnIndexBuildComplete(indexIdentifier) == false at import time.","commonSituations":"Importing SSTables copied while a new SAI index (per-column) was still being built/backfilled; partial file copy missing one column's SAI index file; restore from snapshot taken during CREATE INDEX backfill.","solutions":["Wait for the SAI index build/backfill to finish on the source before copying SSTables","Copy all SSTable components including the per-column SAI index files for every indexed column","Rebuild the specific index before import (drop/recreate or use nodetool rebuild_index)","Import without the index: drop the SAI index, import, then recreate the index on the destination"],"exampleFix":"// before: importing during CREATE INDEX backfill\nnodetool import -- ks table /data/import\n// after: recreate the index after import instead\nnodetool drop_index ks table idx && nodetool import -- ks table /data/import\ncqlsh> CREATE CUSTOM INDEX idx ON ks.table (col) USING 'StorageAttachedIndexing';","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not copy SSTables while CREATE INDEX backfill is running; check build status first","Include every per-column SAI index file in backups/imports","Drop SAI indexes before large copy operations and recreate them after import","Use nodetool snapshots as the source for SSTable imports"],"tags":["sai","sstable","import","index-build"],"backgroundTag":"invalid-state-transition","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"}