apache/cassandra · error · RuntimeException
Error reading key
Error message
Error reading key %s: %s
What it means
While processing a key read from an SSTable or journal segment, an unexpected Throwable was caught. The code only wraps it in a RuntimeException with context when the exception type is in the skip-exception list; otherwise the original is rethrown. The wrapper message names the key that failed and preserves the cause.
Solutions
- Inspect the cause chain of the RuntimeException to find the underlying read/deserialization failure
- Run with --skip-exception-types to tolerate the failing exception class if the corruption is acceptable
- Restore the affected SSTable/journal segment from a backup or snapshot
- Run scrub/verify on the affected SSTables to repair corruption
Example fix
// before throw t; // raw failure aborts the whole run // after // configure the tool to skip known-benign failure types --skip-exception-types java.io.IOException
Defensive patterns
Strategy: try-catch
Validate before calling
// Before running: check sstable/segment files exist and are readable Files.isReadable(Paths.get(desc.filenameFor(Component.DATA)))
Try / catch
try { tool.run(); }
catch (RuntimeException e) {
if (e.getMessage().startsWith("Error reading key ")) {
Throwable cause = e.getCause(); // inspect real read failure
log("key read failed for " + key + ": " + cause);
} else throw e;
} Prevention
- Run scrub/verify after unclean shutdowns before journal tools
- Keep Cassandra versions consistent between writer and reader of the files
- Take a snapshot before offline tool runs so data can be restored
When it happens
Trigger: A deserialization or read failure occurs for a specific key during a standalone journal tool run and the exception's class is listed in --skip-exception-types (or the configured skip set), so instead of propagating the raw error the tool wraps it with 'Error reading key %s: %s'.
Common situations: Corrupt SSTable data or journal segments after a crash; reading files with a different Cassandra version than wrote them; deserializer incompatibilities on partially written files.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Cannot deserialize index summary from
- Clustering block upper bits (those not associated with…
- Corrupt clustering value length
- Corrupt flags value for clustering prefix (isStatic flag…
- Corrupt (negative) clustering value length encountered
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/41e22c80b84a96de.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tools/StandaloneJournalUtil.java:352
boolean shouldSkip = false;
if (skipAllErrors)
{
shouldSkip = true;
}
else if (!skipExceptionTypes.isEmpty())
{
String exceptionClassName = t.getClass().getSimpleName();
String fullExceptionClassName = t.getClass().getName();
shouldSkip = skipExceptionTypes.contains(exceptionClassName) ||
skipExceptionTypes.contains(fullExceptionClassName);
}
if (!shouldSkip)
throw t;
throw new RuntimeException(String.format("Error reading key %s: %s", key, t.getMessage()), t);
}
}
}
@Command(name = "load", description = "Load item from journal")
public static class Load implements Runnable
{
@Option(names = {"-s", "--sstables"}, description = "Path to sstables")
public String sstables;
@Option(names = {"-j", "--journal-segments"}, description = "Path to journal segments")
public String journalSegments;
@Option(names = {"-k", "--kind"}, description = "Kind to filter by")
public String kind;
@Option(names = {"-c", "--command-store-id"}, description = "Command Store id")
public String commandStoreId;View on GitHub (pinned to 88fd0f6a0e)