apache/cassandra · error · IllegalArgumentException
Hash of unexpected size when serializing a Leaf off-heap: "…
Error message
Hash of unexpected size when serializing a Leaf off-heap: " + hash.length
What it means
OffHeapLeaf serialization requires the leaf's hash array to be exactly HASH_SIZE long (or the leaf to be empty); any other length throws IllegalArgumentException('Hash of unexpected size when serializing a Leaf off-heap: ...'). This enforces the fixed wire layout of off-heap leaves.
Solutions
- Ensure leaf hashes are computed with the digest whose output equals HASH_SIZE
- Validate hash.length == MerkleTree.HASH_SIZE before constructing/serializing leaves
- Use MerkleTree's own hash consumers instead of injecting externally computed hashes
- Regenerate the tree if it came from an incompatible version
Example fix
// before byte[] hash = md5.digest(data); // wrong digest length OnHeapLeaf leaf = new OnHeapLeaf(hash); // after byte[] hash = HashingHasher.hash(data); // produces HASH_SIZE bytes assert hash.length == MerkleTree.HASH_SIZE; OnHeapLeaf leaf = new OnHeapLeaf(hash);
Defensive patterns
Strategy: validation
Validate before calling
// Validate before constructing/serializing a leaf
if (hash.length != MerkleTree.HASH_SIZE) {
throw new IllegalArgumentException("Hash must be " + MerkleTree.HASH_SIZE + " bytes, got " + hash.length);
}
OnHeapLeaf leaf = new OnHeapLeaf(hash);
leaf.serializeOffHeap(buffer, partitioner); Type guard
static boolean hasValidHashSize(byte[] hash) {
return hash != null && hash.length == MerkleTree.HASH_SIZE;
} Try / catch
try {
leaf.serializeOffHeap(buffer, partitioner);
} catch (IllegalArgumentException e) {
logger.error("Leaf hash size invalid: {}", e.getMessage());
// recompute the hash with the expected digest and retry once
} Prevention
- Compute leaf hashes only with the digest matching HASH_SIZE
- Never inject hashes produced by other algorithms or versions
- Add an assert on hash.length in test helpers that build trees
- Regenerate trees after upgrading if the hash algorithm changed
When it happens
Trigger: Constructing an OnHeapLeaf/leaf with a hash byte[] whose length differs from MerkleTree.HASH_SIZE (e.g., hashes computed with a different digest) and then serializing it off-heap.
Common situations: Custom code computing leaf hashes with a non-default digest length; trees produced by a different Cassandra version with a different hash algorithm; hand-built leaves in tests.
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
- Hash of unexpected size when deserializing an off-heap Leaf…
- Insufficient remaining bytes to deserialize a Leaf node…
- Hash algorithm not found
- Hash of size encountered, expecting or
- Insufficient remaining bytes to deserialize Inner node…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/2d0df5b80259e0c1.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/utils/MerkleTree.java:1112
{
case HASH_SIZE:
byte[] hash = new byte[HASH_SIZE];
in.readFully(hash);
return new OnHeapLeaf(hash);
case 0:
return new OnHeapLeaf();
default:
throw new IllegalStateException(format("Hash of size %d encountered, expecting %d or %d", size, HASH_SIZE, 0));
}
}
int serializeOffHeap(ByteBuffer buffer, IPartitioner p)
{
if (buffer.remaining() < OffHeapLeaf.maxOffHeapSize())
throw new IllegalStateException("Insufficient remaining bytes to deserialize a Leaf node off-heap");
if (hash.length != HASH_SIZE)
throw new IllegalArgumentException("Hash of unexpected size when serializing a Leaf off-heap: " + hash.length);
final int position = buffer.position();
buffer.put(hash);
return ~position;
}
@Override
public String toString()
{
return "#<OnHeapLeaf " + Node.toString(hash()) + '>';
}
}
static class OffHeapLeaf extends OffHeapNode implements Leaf
{
static final int HASH_BYTES_OFFSET = 0;
OffHeapLeaf(ByteBuffer buffer, int offset)View on GitHub (pinned to 88fd0f6a0e)