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

BigTableScrubber.scrubInternal cross-checks each partition key read from Data.db against the key recorded in Index.db. If they differ, it throws IOError with 'Key from data file (%s) does not match key from index file (%s)' (the data-file key is elided as '_too big_' to avoid huge dumps). This means Data.db and Index.db disagree about partition boundaries — the files are inconsistent.

Source

Thrown at src/java/org/apache/cassandra/io/sstable/format/big/BigTableScrubber.java:158

                    dataStartFromIndex = currentPartitionPositionFromIndex + 2 + currentIndexKey.remaining();
                    dataSizeFromIndex = nextPartitionPositionFromIndex - dataStartFromIndex;
                }
            }

            long dataStart = dataFile.getFilePointer();

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

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

                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))));
                                                                    "_too big_", ByteBufferUtil.bytesToHex(currentIndexKey))));
                }

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

                if (indexFile != 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);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Always copy SSTable generations as a complete component set (Data.db, Index.db, Summary.db, CompressionInfo.db, Statistics.db, TOC.txt) — replace the mixed set with a consistent backup.
  2. Remove the inconsistent SSTable and run `nodetool repair` to re-replicate correct data.
  3. Run `nodetool scrub` with appropriate options; if scrub can't reconcile, offline `sstables scrub`/`sstableverify` can help diagnose.
  4. Check for interrupted compactions on this table and disk errors in system logs.

Example fix

// before: partial copy of sstable components
cp *-big-Data.db /backup/
// after: copy all components of each generation
cp *-big-*.db /backup/  # includes Index.db, Summary.db, Statistics.db, TOC.txt
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: sanity-check that Data.db and Index.db belong together via generation + creation time
assert dataFile.getPath().replaceAll("-big-Data.db", "")
       .equals(indexFile.getPath().replaceAll("-big-Index.db", ""));

Try / catch

try {
    scrubber.scrub();
} catch (IOError e) {
    if (e.getMessage().contains("does not match key from index file")) {
        quarantineSstableGeneration(desc); // move all components aside
        runRepair();
    } else throw e;
}

Prevention

When it happens

Trigger: During scrub, dataFile key != currentIndexKey: Index.db from a different generation of the file, corrupted key bytes in either file, or a partially overwritten Data.db whose partition boundary drifted from the index.

Common situations: Mixing components from different SSTable generations when copying/backing up files; interrupted compaction or write leaving inconsistent pairs; disk corruption affecting one file but not the other; hand-edited/moved SSTable 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/fcc647f7488af48f. Report an issue: GitHub.