elastic/elasticsearch · error · LZ4Exception
Too large literalLen
Error message
Too large literalLen
What it means
When the literal-length nibble equals RUN_MASK (15), the decoder reads a chain of 0xFF extension bytes, adding 255 each time. If the accumulated literalLen overflows int (goes negative), the declared literal length exceeds any plausible buffer and the stream is malformed. This bounds the variable-length literal encoding.
Source
Thrown at libs/lz4/src/main/java/org/elasticsearch/lz4/ESLZ4Decompressor.java:88
int sOff = srcOff;
int dOff = destOff;
while (true) {
if (sOff >= srcEnd) {
throw new LZ4Exception("Malformed input at " + sOff);
}
final int token = SafeUtils.readByte(src, sOff) & 0xFF;
++sOff;
// literals
int literalLen = token >>> ML_BITS;
if (literalLen == RUN_MASK) {
byte len = (byte) 0xFF;
while (sOff < srcEnd && (len = SafeUtils.readByte(src, sOff++)) == (byte) 0xFF) {
literalLen += 0xFF;
if (literalLen < 0) {
throw new LZ4Exception("Too large literalLen");
}
}
literalLen += len & 0xFF;
}
final int literalCopyEnd = dOff + literalLen;
// Check for overflow
if (literalCopyEnd < dOff) {
throw new LZ4Exception("Too large literalLen");
}
if (notEnoughSpace(destEnd - literalCopyEnd, COPY_LENGTH) || notEnoughSpace(srcEnd - sOff, COPY_LENGTH + literalLen)) {
if (literalCopyEnd != destEnd) {
throw new LZ4Exception("Malformed input at " + sOff);
} else if (notEnoughSpace(srcEnd - sOff, literalLen)) {
throw new LZ4Exception("Malformed input at " + sOff);
View on GitHub (pinned to db6a809a66)
Solutions
- Treat the input as corrupt; do not trust the source block.
- Restore the data from a known-good replica or snapshot.
- If generating the input programmatically, ensure the literal-length encoding matches the LZ4 spec.
Defensive patterns
Strategy: try-catch
Validate before calling
// No safe pre-check; overflow is detected during decode. Bound the declared destLen against srcLen as a heuristic.
if (destLen > srcLen * 255L) { // literals can't expand more than ~255x
throw new IllegalArgumentException("Implausible LZ4 destLen for given srcLen");
} Try / catch
try {
ESLZ4Decompressor.INSTANCE.decompress(src, srcOff, dest, destOff, destLen);
} catch (LZ4Exception e) {
// literal-length overflow => corrupt or adversarial input
markCorruptAndRecover();
} Prevention
- Reject implausible destLen/srcLen ratios before decompression.
- Treat any LZ4Exception during decode as corrupt input.
- Do not attempt to repair corrupt blocks in place; recover from replicas.
When it happens
Trigger: Decompressing an LZ4 block whose literal-length extension bytes sum beyond Integer.MAX_VALUE, i.e. more than ~8.4 million 0xFF bytes precede the terminating length byte. Indicates crafted or severely corrupt input.
Common situations: Fuzzed or adversarial LZ4 input. Memory corruption that overwrites length bytes with 0xFF. A buffer from an incompatible LZ4 implementation.
Related errors
- Too large matchLen
- Malformed input at {}
- Failed when reading jar file ${path}
- time value cannot store values greater than 106751 days
- Resolution overflow
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/230232e1c840b98b.
Report an issue: GitHub.