{"record":{"id":"108494fb2c32661f","repo":"apache/cassandra","slug":"unable-to-delete-storage-attached-index-component","errorCode":null,"errorMessage":"Unable to delete storage-attached index component file {} due to {}.","messagePattern":"Unable to delete storage-attached index component file (.+?) due to (.+?)\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/index/sai/disk/format/IndexDescriptor.java","lineNumber":490,"sourceCode":"    {\n        return version.onDiskFormat()\n                      .perColumnIndexComponents(indexTermType)\n                      .stream()\n                      .map(c -> fileFor(c, indexIdentifier))\n                      .filter(File::exists)\n                      .count();\n    }\n\n    private void deleteComponent(File file)\n    {\n        logger.debug(logMessage(\"Deleting storage-attached index component file {}\"), file);\n        try\n        {\n            IOUtils.deleteFilesIfExist(file.toPath());\n        }\n        catch (IOException e)\n        {\n            logger.warn(logMessage(\"Unable to delete storage-attached index component file {} due to {}.\"), file, e.getMessage(), e);\n        }\n    }\n}\n","sourceCodeStart":472,"sourceCodeEnd":494,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/sai/disk/format/IndexDescriptor.java#L472-L494","documentation":"IndexDescriptor.deleteComponent deletes an SAI per-component file (e.g. a per-column index segment, metadata, or checksum file) with IOUtils.deleteFilesIfExist. If the delete fails with an IOException (file locked, permission denied, FS error), the code logs a warning including the IOException message instead of throwing, because index cleanup is best-effort. Leftover files are orphaned but harmless since the SSTable descriptor tracks live components.","triggerScenarios":"Deleting index files during index drop, SSTable removal, or abort of an index writer while the file is still memory-mapped/open by another thread (Windows file locking) or the directory has wrong permissions; disk I/O errors during cleanup.","commonSituations":"Dropping a SAI index on Windows while readers still hold files open; read-only or quota-exceeded volume after a crash; concurrent abort and delete paths racing on the same component files.","solutions":["Check filesystem permissions and free space on the data directory where the component file lives.","On Windows, ensure all Cassandra threads using the file have finished before removal, or configure cassandra.yaml file_cache / mmap settings to non-mmap (disk_access_mode: standard) to avoid lingering mapped handles.","Manually remove orphaned component files that match the SSTable descriptor pattern once the SSTable is no longer live.","Check disk health (dmesg / smartctl) if the IOException message indicates an I/O error."],"exampleFix":"// before: adjusting platform to avoid locked deletes on Windows\ncassandra.yaml: disk_access_mode: mmap\n// after\ncassandra.yaml: disk_access_mode: standard","handlingStrategy":"validation","validationCode":"// before component deletion\ndir = file.getParent().toFile();\nif (!dir.canWrite()) logger.warn(\"Index dir not writable: \" + dir);","typeGuard":null,"tryCatchPattern":"// deleteComponent already swallows IOException; wrap bulk cleanup\ntry { descriptor.deleteAllComponents(); }\ncatch (Throwable t) { logger.warn(\"Cleanup incomplete, orphan files possible\", t); }","preventionTips":["Ensure the Cassandra process user owns the data directories and they are writable.","On Windows, avoid mmap (disk_access_mode: standard) to reduce locked-file deletes.","Monitor free disk space so deletes don't fail on quota/ENOSPC."],"tags":["filesystem","io","cleanup","index"],"backgroundTag":"file-write-failed","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"}