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

  1. Log both the expected (len) and actual (buffer.limit()) sizes to understand the discrepancy magnitude.
  2. Check if the event is truncated — if actual < expected, the compressed payload was cut short.
  3. Verify the lenPad byte parsing: len comes from getUncompressLong(lenPad & 0x07), which encodes the length type (1, 2, 3, or 4 byte length field).
  4. 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

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.