apache/cassandra · error · IllegalStateException

Hash of unexpected size when deserializing an off-heap Leaf…

Error message

Hash of unexpected size when deserializing an off-heap Leaf node: " + hashLength

What it means

OffHeapLeaf.deserializeWithoutIdent reads a hash length byte; a non-zero length must equal HASH_SIZE, otherwise it throws IllegalStateException('Hash of unexpected size when deserializing an off-heap Leaf node: ...'). The off-heap leaf layout stores either 0 (empty) or exactly HASH_SIZE hash bytes.

Solutions

  1. Confirm all repair participants run versions with the same HASH_SIZE
  2. Regenerate the tree via a fresh repair validation
  3. Check for stream truncation/offset desync before the leaf read
  4. Inspect the reported hashLength to distinguish corruption from version skew
Defensive patterns

Strategy: try-catch

Try / catch

try {
    OffHeapLeaf.deserializeWithoutIdent(in, buffer);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Hash of unexpected size")) {
        logger.error("Corrupt or version-mismatched off-heap leaf: {}", e.getMessage());
        // discard the tree and re-run repair validation
    }
    throw e;
}

Prevention

When it happens

Trigger: Deserializing an off-heap leaf whose stored hash-length byte is neither 0 nor HASH_SIZE — data written by an incompatible Cassandra version (different hash size), stream corruption, or misaligned reads.

Common situations: Repair across mixed versions where digest output size changed; corrupted MerkleTree payloads in flight or at rest; reading at a wrong offset so an arbitrary byte is interpreted as the length.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/utils/MerkleTree.java:1151

        }

        public int hashBytesOffset()
        {
            return offset + HASH_BYTES_OFFSET;
        }

        static int deserializeWithoutIdent(DataInput in, ByteBuffer buffer) throws IOException
        {
            if (buffer.remaining() < maxOffHeapSize())
                throw new IllegalStateException("Insufficient remaining bytes to deserialize a Leaf node off-heap");

            final int position = buffer.position();

            int hashLength = in.readByte();
            if (hashLength > 0)
            {
                if (hashLength != HASH_SIZE)
                    throw new IllegalStateException("Hash of unexpected size when deserializing an off-heap Leaf node: " + hashLength);

                byte[] hashBytes = getTempArray(HASH_SIZE);
                in.readFully(hashBytes, 0, HASH_SIZE);
                buffer.put(hashBytes, 0, HASH_SIZE);
            }
            else
            {
                buffer.put(EMPTY_HASH, 0, HASH_SIZE);
            }

            return ~position;
        }

        static int maxOffHeapSize()
        {
            return HASH_SIZE;
        }

View on GitHub (pinned to 88fd0f6a0e)