apache/cassandra · error · IOException
Corrupt (negative) clustering value length encountered: ${le
Error message
Corrupt (negative) clustering value length encountered: ${length} What it means
validateClusteringValueLength rejects a negative length read from disk for a clustering value. A negative length cannot be a valid encoded size, so the bytes are corrupt and an IOException is thrown; callers wrap it in CorruptSSTableException.
Source
Thrown at src/java/org/apache/cassandra/io/sstable/SSTableCursorReader.java:1105
validateClusteringValueLength(varLength);
clustering.writeUnsignedVInt(varLength);
clustering.loadPart(dataReader, varLength);
return 0;
}
/**
* Rejects a clustering value length the wire cannot have produced honestly. Both checks mirror
* AbstractType.read, the reference for this format. readUnsignedVInt32 can return a negative
* int, which is why the first check exists: an unchecked negative length reaches
* {@link java.io.DataInput#skipBytes} as a silent no-op, and a buffer sizer as a defect.
*
* <p>Every caller of this walk wraps it and reports a {@code CorruptSSTableException}.
*/
@VisibleForTesting
static void validateClusteringValueLength(int length) throws IOException
{
if (length < 0)
throw new IOException("Corrupt (negative) clustering value length encountered: " + length);
if (length > DatabaseDescriptor.getMaxValueSize())
throw new IOException(String.format("Corrupt clustering value length %d encountered, as it exceeds the maximum of %d, " +
"which is set via max_value_size in cassandra.yaml",
length, DatabaseDescriptor.getMaxValueSize()));
}
private static void skipClustering(RandomAccessReader dataReader, AbstractType<?>[] types, int clusteringColumnsBound) throws IOException
{
long clusteringBlockHeader = 0;
for (int clusteringIndex = 0; clusteringIndex < clusteringColumnsBound; clusteringIndex++)
{
// struct clustering_block {
// varint clustering_block_header;
// simple_cell[] clustering_cells;
// };
if (clusteringIndex % 32 == 0)
{
clusteringBlockHeader = dataReader.readUnsignedVInt();View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Run nodetool verify / sstableverify to confirm corruption.
- Run nodetool scrub (sstablescrub) to salvage or quarantine the affected sstable.
- Restore the file from backup and run nodetool repair to restore replication consistency.
- If reads are misaligned, fix the preceding deserialization code so offsets stay correct.
Example fix
// before int len = in.readUnsignedShort(); skipClustering(in, types, len); // after int len = in.readUnsignedShort(); validateClusteringValueLength(len); // throws on negative/oversized before use skipClustering(in, types, len);
Defensive patterns
Strategy: try-catch
Validate before calling
if (length < 0) throw new IOException("negative clustering length: " + length); Try / catch
try {
value = readClusteringValue(in);
} catch (IOException e) {
if (e.getMessage().contains("Corrupt"))
throw new CorruptSSTableException(e, filename);
throw e;
} Prevention
- Monitor disks (SMART/dmesg) for hardware corruption sources.
- Verify sstables after unclean shutdowns.
- Use digest-verified binary copies when moving sstables.
- Scrub sstables flagged by verify promptly.
When it happens
Trigger: Deserializing/skipping clustering values where the on-disk length prefix decodes to a negative int — corrupted sstable bytes or misaligned reads following earlier corruption.
Common situations: Disk/bit-flip corruption; sstables truncated or written by a buggy writer; cursor misalignment after a prior deserialization bug.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Corrupt flags value for clustering prefix (isStatic flag set
- Clustering block upper bits (those not associated with keys)
- Corrupt clustering value length %d encountered, as it exceed
- CorruptSSTableException (wrapped corruption: IndexOutOfBound
- Invalid Columns subset bytes; too many bits set: ${encoded}
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/ff6b487df842b66c.
Report an issue: GitHub.