{"record":{"id":"ec58aa78a2062e9d","repo":"apache/cassandra","slug":"aborting-sstable-index-flush-for","errorCode":null,"errorMessage":"Aborting SSTable index flush for {}...","messagePattern":"Aborting SSTable index flush for (.+?)\\.\\.\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/index/sai/disk/v1/SSTableIndexWriter.java","lineNumber":187,"sourceCode":"        finally\n        {\n            index.indexMetrics().segmentsPerCompaction.update(segments.size());\n            segments.clear();\n            index.indexMetrics().compactionCount.inc();\n        }\n    }\n\n    @Override\n    public void abort(Throwable cause)\n    {\n        aborted = true;\n\n        String message = index.identifier().logMessage(\"Aborting SSTable index flush for {}...\");\n\n        if (cause == null)\n            logger.debug(message, indexDescriptor.sstableDescriptor);\n        else \n            logger.warn(message, indexDescriptor.sstableDescriptor, cause);\n\n        // It's possible for the current builder to be unassigned after we flush a final segment.\n        if (currentBuilder != null)\n        {\n            // If an exception is thrown out of any writer operation prior to successful segment\n            // flush, we will end up here, and we need to free up builder memory tracked by the limiter:\n            long allocated = currentBuilder.totalBytesAllocated();\n            long globalBytesUsed = currentBuilder.release();\n            logger.debug(index.identifier().logMessage(\"Aborting index writer for SSTable {} released {}. Global segment memory usage now at {}.\"),\n                         indexDescriptor.sstableDescriptor, FBUtilities.prettyPrintMemory(allocated), FBUtilities.prettyPrintMemory(globalBytesUsed));\n        }\n\n        indexDescriptor.deleteColumnIndex(index.termType(), index.identifier());\n    }\n\n    /**\n     * abort current write if index is dropped\n     *","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/sai/disk/v1/SSTableIndexWriter.java#L169-L205","documentation":"SSTableIndexWriter.abort is invoked when an SAI SSTable index write is aborted, from indexSSTable (exception during build), maybeAbort (segment writer failure), or writeSegmentsMetadata. Like MemtableIndexWriter.abort, cause == null is the benign no-flush-needed path (DEBUG); a non-null cause is a real failure logged at WARN. The abort releases segment-builder memory tracked by the global limiter and deletes partial on-disk index components.","triggerScenarios":"An exception is thrown out of any writer operation before the segment flush succeeds (disk I/O error, out-of-memory in the index write buffer); the flush is cancelled because the final segment was already written; index_sai_segment_write_memory_limit exhaustion causing writer failure.","commonSituations":"Disk full during index build; write buffer allocation failures under the segment write memory limit; node shutdown mid-build; concurrent SSTable lifecycle changes invalidating the in-progress build.","solutions":["Read the attached cause in the WARN log — it names the real failure (usually IOException or OutOfMemoryError).","If memory-related, lower cassandra.yaml `column_index_size_in_kb`/segment size or raise `sai.segment_write_buffer_size` headroom; ensure heap and off-heap limits accommodate concurrent index builds.","Free disk space in the data directory and re-trigger the build (`nodetool scsirebuild` or recreate the index).","If aborts recur on the same SSTable, drop and recreate the index to rebuild from a clean state."],"exampleFix":"// before: default segment write memory, builds OOM under heavy load\n# cassandra.yaml\nsai_coordinator_resume: true\n// after: tune limits and rebuild\n# cassandra.yaml\nsai: { segment_write_buffer_size: 1024 }\n# then: nodetool scsirebuild --index my_index keyspace table","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// ensure memory tracked by the limiter is released even on unexpected paths\ntry { writeSegmentsMetadata(); }\ncatch (Throwable t) { writer.abort(t); throw t; }","preventionTips":["Size segment write buffers and heap for concurrent index builds; watch the SAI segment memory limiter metrics.","Ensure adequate free disk space before large index builds.","Rebuild affected indexes after repeated aborts rather than relying on partial state."],"tags":["sstable","index-build","flush","abort"],"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-14T11:17:12.474Z"}