alibaba/canal · error · IllegalArgumentException
uncompress lenght not match, expected : , but actual :
Error message
uncompress lenght not match, expected : , but actual :
What it means
Thrown after successful zlib decompression when the decompressed data length does not match the expected uncompressed length (len, decoded from the event header). The expected length is derived from getUncompressLong(lenPad & 0x07). A mismatch means the compressed stream decompressed to a different size than the header declared, indicating corruption in either the header or the compressed payload.
Source
Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/LogBuffer.java:1768
int lenPad = getInt8();
long len = getUncompressLong(lenPad & 0x07);
int alg = (lenPad & 0x70) >> 4;
LogBuffer buffer = null;
try {
switch (alg) {
case 0:
buffer = uncompressZlib(limit - position);
break;
default:
// bad algorithm
return this;
}
} catch (Exception e) {
throw new IllegalArgumentException("uncompress failed ", e);
}
if (buffer.limit() != len) {
throw new IllegalArgumentException(
"uncompress lenght not match, expected : " + len + " , but actual : " + buffer.limit());
}
return buffer;
}
private LogBuffer uncompressZlib(int len) throws Exception {
if (position + len > limit || position < 0) {
throw new IllegalArgumentException("limit excceed: " + (position + len));
}
try (DeflateCompressorInputStream in = new DeflateCompressorInputStream(
new ByteArrayInputStream(buffer, position, position + len))) {
byte[] decodeBytes = IOUtils.toByteArray(in);
return new LogBuffer(decodeBytes, 0, decodeBytes.length);
}
}
/**
View on GitHub (pinned to 87be50e876)
Solutions
- Log both the expected (len) and actual (buffer.limit()) sizes to understand the discrepancy magnitude.
- Check if the event is truncated — if actual < expected, the compressed payload was cut short.
- Verify the lenPad byte parsing: len comes from getUncompressLong(lenPad & 0x07), which encodes the length type (1, 2, 3, or 4 byte length field).
- Re-synchronize replication from a known-good binlog position.
Defensive patterns
Strategy: try-catch
Validate before calling
// After decompression, the library checks buffer.limit() == len. // Callers can pre-validate by checking the expected uncompressed size from the event header. // This is done internally by uncompressBuf(); no external pre-check is available.
Try / catch
try {
LogBuffer decompressed = buffer.uncompressBuf();
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("uncompress lenght not match")) {
logger.warn("Decompressed size mismatch — corrupt compressed payload or wrong length header");
}
throw e;
} Prevention
- Verify the lenPad byte is correctly parsed — the uncompressed length encoding depends on lenPad & 0x07.
- Check for binlog corruption if the mismatch is consistent across events.
- Monitor MariaDB version changes that might alter the compression header format.
When it happens
Trigger: LogBuffer.uncompressBuf() successfully decompresses data via uncompressZlib(), but buffer.limit() (actual decompressed size) != len (expected size from the 3-bit length encoding in the event header). Note the typo 'lenght' in the message.
Common situations: Corrupt compressed event where the header's declared uncompressed size is wrong, a truncated compressed stream that Apache Commons Compress partially decoded, or a binlog produced by a MariaDB version with a different compression length encoding.
Related errors
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/1067d966d9b25f72.
Report an issue: GitHub.