apache/cassandra · critical · IOError

Key from data file (%s) does not match key from index file (

Error message

Key from data file (%s) does not match key from index file (%s)

What it means

Thrown during BTI sstable scrub when the partition key read from the data file does not match the key recorded in the index file for the same partition. This indicates index/data divergence — the data file content is not at the position the index expects, a strong sign of file corruption or interleaved/mismatched components.

Source

Thrown at src/java/org/apache/cassandra/io/sstable/format/bti/BtiTableScrubber.java:177

                        indexIterator = null;
                        currentIndexKey = null;
                        dataStartFromIndex = -1;
                        dataSizeFromIndex = -1;
                    }
                }
            }

            String keyName = key == null ? "(unreadable key)" : keyString(key);
            outputHandler.debug("partition %s is %s", keyName, FBUtilities.prettyPrintMemory(dataSizeFromIndex));

            try
            {
                if (key == null)
                    throw new IOError(new IOException("Unable to read partition key from data file", keyReadError));

                if (currentIndexKey != null && !key.getKey().equals(currentIndexKey))
                {
                    throw new IOError(new IOException(String.format("Key from data file (%s) does not match key from index file (%s)",
                                                                    ByteBufferUtil.bytesToHex(key.getKey()), ByteBufferUtil.bytesToHex(currentIndexKey))));
                }

                if (indexIterator != null && dataSizeFromIndex > dataFile.length())
                    throw new IOError(new IOException("Impossible partition size (greater than file length): " + dataSizeFromIndex));

                if (indexIterator != null && dataStart != dataStartFromIndex)
                    outputHandler.warn("Data file partition position %d differs from index file row position %d", dataStart, dataStartFromIndex);

                if (tryAppend(prevKey, key, writer))
                    prevKey = key;
            }
            catch (Throwable th)
            {
                throwIfFatal(th);
                outputHandler.warn(th, "Error reading partition %s (stacktrace follows):", keyName);

                if (currentIndexKey != null

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Restore the complete, matching set of sstable components (Data.db, Index.db, etc.) from backup
  2. Drop the corrupt sstable and run repair to stream data from replicas
  3. Check that sstable files were not manually renamed — component generation must match the TOC
  4. Scrub with --no-validate to salvage what is readable, accepting some data loss
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure index and data components belong to the same generation before scrub
if (!dataFile.getName().equals(indexFile.getName())) throw new IllegalStateException("component generation mismatch");

Try / catch

try { scrubInternal(...); } catch (IOError e) { logger.error("index/data key mismatch: restore matching components", e); }

Prevention

When it happens

Trigger: Scrubbing a BTI sstable where the data file was modified, truncated, or mixed with a different generation's index file; dataStart points to a different partition than currentIndexKey.

Common situations: Manually copied or renamed sstable components mixing generations, restore of partial backups, corruption from hardware failure, upgrades leaving mismatched components.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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