apache/cassandra · error · IllegalStateException

Missing SAI index to import for index %s on %s.%s

Error message

Missing SAI index to import for index %s on %s.%s

What it means

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.

Source

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

                                {
                                    IndexDescriptor indexDescriptor = IndexDescriptor.create(descriptor,
                                                                                             cfs.getPartitioner(),
                                                                                             cfs.metadata().comparator);

                                    String keyspace = cfs.getKeyspaceName();
                                    String table = cfs.getTableName();

                                    if (!indexDescriptor.isPerSSTableIndexBuildComplete())
                                        throw new IllegalStateException(String.format("Missing SAI index to import for SSTable %s on %s.%s",
                                                                                      indexDescriptor.sstableDescriptor.toString(),
                                                                                      keyspace,
                                                                                      table));

                                    for (Index index : saiIndexGroup.getIndexes())
                                    {
                                        IndexIdentifier indexIdentifier = new IndexIdentifier(keyspace, table, index.getIndexMetadata().name);
                                        if (!indexDescriptor.isPerColumnIndexBuildComplete(indexIdentifier))
                                            throw new IllegalStateException(String.format("Missing SAI index to import for index %s on %s.%s",
                                                                                          index.getIndexMetadata().name,
                                                                                          keyspace,
                                                                                          table));
                                    }
                                }
                            }

                            if (options.verifySSTables || options.verifyTokens)
                                verifySSTableForImport(descriptor, entry.getValue(), options.verifyTokens, options.verifySSTables, options.extendedVerify);
                        }
                        catch (Throwable t)
                        {
                            if (dir != null)
                            {
                                logger.error("[{}] Failed verifying SSTable {} in directory {}", importID, descriptor, dir, t);
                                failedDirectories.add(dir);
                            }
                            else

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Wait for the SAI index build/backfill to finish on the source before copying SSTables
  2. Copy all SSTable components including the per-column SAI index files for every indexed column
  3. Rebuild the specific index before import (drop/recreate or use nodetool rebuild_index)
  4. Import without the index: drop the SAI index, import, then recreate the index on the destination

Example fix

// before: importing during CREATE INDEX backfill
nodetool import -- ks table /data/import
// after: recreate the index after import instead
nodetool drop_index ks table idx && nodetool import -- ks table /data/import
cqlsh> CREATE CUSTOM INDEX idx ON ks.table (col) USING 'StorageAttachedIndexing';
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: importNewSSTables iterates saiIndexGroup.getIndexes(); for one index the SSTable's descriptor reports isPerColumnIndexBuildComplete(indexIdentifier) == false at import time.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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