{"record":{"id":"5a2d385bf1f5a232","repo":"apache/cassandra","slug":"failed-for-index-component-on-sstable","errorCode":null,"errorMessage":"{} failed for index component {} on SSTable {}","messagePattern":"(.+?) failed for index component (.+?) on SSTable (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/index/sai/disk/v1/V1OnDiskFormat.java","lineNumber":338,"sourceCode":"    }\n\n    private static void validateIndexComponent(IndexDescriptor indexDescriptor,\n                                               IndexIdentifier indexContext,\n                                               IndexComponent indexComponent,\n                                               boolean checksum)\n    {\n        try (IndexInput input = indexContext == null\n                                ? indexDescriptor.openPerSSTableInput(indexComponent)\n                                : indexDescriptor.openPerIndexInput(indexComponent, indexContext))\n        {\n            if (checksum)\n                SAICodecUtils.validateChecksum(input);\n            else\n                SAICodecUtils.validate(input);\n        }\n        catch (Exception e)\n        {\n            logger.warn(indexDescriptor.logMessage(\"{} failed for index component {} on SSTable {}\"),\n                        checksum ? \"Checksum validation\" : \"Validation\", indexComponent, indexDescriptor.sstableDescriptor);\n            rethrowIOException(e);\n        }\n    }\n\n    private static void rethrowIOException(Exception e)\n    {\n        if (e instanceof IOException)\n            throw new UncheckedIOException((IOException) e);\n        if (e.getCause() instanceof IOException)\n            throw new UncheckedIOException((IOException) e.getCause());\n        throw Throwables.unchecked(e);\n    }\n\n    @Override\n    public Set<IndexComponent> perSSTableIndexComponents(boolean hasClustering)\n    {\n        return hasClustering ? WIDE_PER_SSTABLE_COMPONENTS : SKINNY_PER_SSTABLE_COMPONENTS;","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/index/sai/disk/v1/V1OnDiskFormat.java#L320-L356","documentation":"V1OnDiskFormat.validateIndexComponent logs this warning when opening/checking a Storage-Attached Index (SAI) index component file on an SSTable throws an exception. Depending on whether the component was written with a checksum, either SAICodecUtils.validateChecksum or SAICodecUtils.validate failed, meaning the on-disk index component is corrupt, unreadable, or was written by an incompatible version. After logging, the exception is rethrown as an IOException, so callers (compaction, index build, query path) will see the failure propagate.","triggerScenarios":"Calling validatePerSSTableIndexComponents or validatePerColumnIndexComponents during SAI index load/repair when an index component file (e.g. .tok, .kdi, meta files) is truncated, bit-rotted on disk, or fails CRC/checksum verification in SAICodecUtils.","commonSituations":"Disk corruption or failing hardware on a node; an interrupted compaction or flush left a partial index component; the SSTable was copied/restored manually and files are inconsistent; a Cassandra version upgrade changed the index component format and validation logic rejects older files.","solutions":["Run nodetool scrub or repair on the affected SSTables to rebuild damaged index components, or run an offline full scrub with --no-sanity-checks if needed","Drop and rebuild the SAI index (DROP INDEX then CREATE INDEX) so all per-SSTable index components are regenerated from live data","Check dmesg/filesystem health (xfs_repair/fsck) on the node; move the node out of rotation and replace the damaged disk","Restore the SSTable set from a good snapshot or backup if the index components and data files are inconsistent"],"exampleFix":"// before: trusting SSTables copied from another node\nFiles.copy(srcIndexComponent, destIndexComponent);\n// after: rebuild index components on the target node instead of copying them\nnodetool repair -pr keyspace table; // then DROP/CREATE INDEX to regenerate SAI components","handlingStrategy":"validation","validationCode":"// before loading an SSTable's SAI index, verify components exist and are non-empty\nfor (String comp : expectedIndexComponents)\n{\n    File f = new File(sstableDir, baseName + comp);\n    if (!f.exists() || f.length() == 0)\n        throw new IOException(\"Index component missing or empty: \" + f);\n}","typeGuard":null,"tryCatchPattern":"try { format.validateIndexComponents(descriptor, ...); }\ncatch (IOException e)\n{\n    logger.error(\"Index component validation failed for {} - marking index unusable and scheduling rebuild\", descriptor, e);\n    rebuildIndex();\n}","preventionTips":["Monitor disk health (SMART, dmesg) and take nodes with IO errors out of service promptly","Use snapshots/backups that include index component files, not just data files","After upgrades or SSTable moves, run nodetool verify/scrub to validate files before serving traffic","Keep checksum validation enabled so corruption is caught early"],"tags":["sai","index","corruption","io"],"backgroundTag":"checksum-mismatch","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"}