{"record":{"id":"a3484fb12f5b0f55","repo":"apache/cassandra","slug":"the-index-s-has-not-yet-been-upgraded-to-support","errorCode":null,"errorMessage":"The index %s has not yet been upgraded to support prefix queries in CONTAINS mode. Wait for compaction or rebuild the index.","messagePattern":"The index (.+?) has not yet been upgraded to support prefix queries in CONTAINS mode\\. Wait for compaction or rebuild the index\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/index/sasi/TermIterator.java","lineNumber":105,"sourceCode":"        RangeIterator<Long, Token> memtableIterator = e.index.searchMemtable(e);\n        if (memtableIterator != null)\n        {\n            tokens.add(memtableIterator);\n            tokenCount.addAndGet(memtableIterator.getCount());\n        }\n\n        final Set<SSTableIndex> referencedIndexes = new CopyOnWriteArraySet<>();\n\n        try\n        {\n            final CountDownLatch latch = newCountDownLatch(perSSTableIndexes.size());\n            final ExecutorService searchExecutor = SEARCH_EXECUTOR.get();\n\n            for (final SSTableIndex index : perSSTableIndexes)\n            {\n                if (e.getOp() == PREFIX &&\n                    index.mode() == CONTAINS && !index.hasMarkedPartials())\n                    throw new UnsupportedOperationException(format(\"The index %s has not yet been upgraded \" +\n                                                                          \"to support prefix queries in CONTAINS mode. \" +\n                                                                          \"Wait for compaction or rebuild the index.\",\n                                                                          index.getPath()));\n\n\n                if (!index.reference())\n                {\n                    latch.decrement();\n                    continue;\n                }\n\n                // add to referenced right after the reference was acquired,\n                // that helps to release index if something goes bad inside of the search\n                referencedIndexes.add(index);\n\n                searchExecutor.submit((Runnable) () -> {\n                    try\n                    {","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/sasi/TermIterator.java#L87-L123","documentation":"Prefix (non-CONTAINS) SASI queries in CONTAINS-mode indexes require per-sstable indexes with 'marked partial' tokens written by the newer format. TermIterator.build throws this UnsupportedOperationException when a per-SSTable index is still in CONTAINS mode without markedPartials support, i.e. the SSTable index was written by an older version.","triggerScenarios":"Executing a PREFIX (or mixed PREFIX/CONTAINS) expression against a SASI index where at least one SSTable's on-disk index predates the marked-partials format: index.mode() == CONTAINS and !index.hasMarkedPartials().","commonSituations":"Upgrading Cassandra with existing SASI indexes and querying before compaction rewrites old SSTables; restoring old SSTable backups under a new version; running mixed-version clusters during rolling upgrade.","solutions":["Trigger compaction on the table (nodetool compact <keyspace> <table>) so old SSTable indexes are rewritten with marked partials.","Or rebuild the index: DROP INDEX then CREATE CUSTOM INDEX again.","Re-run the query once all SSTables have been rewritten.","Avoid PREFIX queries on that column until upgrade/compaction completes."],"exampleFix":"// before (query fails until compaction)\nSELECT * FROM users WHERE email PREFIX ?; // or CONTAINS on old index\n// after: rebuild the index\nDROP INDEX users_email_idx;\nCREATE CUSTOM INDEX users_email_idx ON users (email) USING 'org.apache.cassandra.index.sasi.SASIIndex'\n  WITH OPTIONS = {'target': 'email', 'mode': 'CONTAINS', 'analyzed': 'true'};","handlingStrategy":"validation","validationCode":"// after upgrade, before issuing PREFIX queries on CONTAINS indexes:\n// run nodetool compact <ks> <table> and confirm all SSTables are rewritten,\n// or proactively rebuild: DROP INDEX ...; CREATE CUSTOM INDEX ...;","typeGuard":null,"tryCatchPattern":"try {\n    session.execute(prefixQuery);\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"has not yet been upgraded to support prefix queries\")) {\n        scheduleIndexRebuild();\n        return fallbackToContainsQuery();\n    }\n    throw e;\n}","preventionTips":["After upgrading Cassandra, always compact or rebuild SASI indexes before running mixed PREFIX/CONTAINS queries.","Include SASI index rebuild in the rolling-upgrade runbook.","Avoid restoring pre-upgrade SSTable backups onto newer nodes."],"tags":["sasi","index-format","upgrade","compatibility","cassandra"],"backgroundTag":"feature-not-enabled","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"}