alibaba/canal · error · IllegalArgumentException

limit excceed:

Error message

limit excceed: 

What it means

Thrown by uncompressZlib() before attempting decompression when the requested read range [position, position+len) exceeds the buffer's limit, or position is negative. This is a bounds check on the compressed data region within the LogBuffer before it is passed to DeflateCompressorInputStream. Note the typo 'excceed' in the message.

Source

Thrown at dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/LogBuffer.java:1776

                    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);
        }
    }

    /**
     * Return full hexdump from position.
     */
    public final String hexdump(final int pos) {
        if ((limit - pos) > 0) {
            final int begin = origin + pos;
            final int end = origin + limit;

            byte[] buf = buffer;

View on GitHub (pinned to 87be50e876)

Solutions

  1. Verify buffer.position() and buffer.limit() before calling uncompressBuf().
  2. Check that the event's declared length matches the buffer's remaining bytes.
  3. Trace the buffer position from the event header parse to find where it diverged.
  4. Ensure no prior consume() or forward() call advanced position beyond the compressed data region.

Example fix

// before
LogBuffer decompressed = buffer.uncompressBuf();

// after: pre-validate buffer state
if (buffer.position() < 0 || buffer.remaining() <= 0) {
    logger.warn("Buffer in invalid state for decompression: pos={}, limit={}",
        buffer.position(), buffer.limit());
    return buffer;
}
LogBuffer decompressed = buffer.uncompressBuf();
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate buffer state before decompression
if (buffer.position() < 0 || buffer.position() > buffer.limit()) {
    logger.warn("Buffer position {} is out of range [0, {}]", buffer.position(), buffer.limit());
    return buffer; // or throw a domain-specific exception
}
if (buffer.remaining() <= 0) {
    logger.warn("No data remaining to decompress");
    return buffer;
}

Try / catch

try {
    LogBuffer decompressed = buffer.uncompressBuf();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("limit excceed")) {
        logger.warn("Buffer bounds exceeded during decompression: pos={}, limit={}",
            buffer.position(), buffer.limit());
    }
    throw e;
}

Prevention

When it happens

Trigger: uncompressZlib is called with len = limit - position (the remaining bytes). If position + len > limit or position < 0, the exception fires. This can happen if the buffer was already consumed past the compressed data region, or if limit was set incorrectly.

Common situations: Buffer position advanced past the compressed data by earlier parsing logic, an incorrect limit set during buffer creation, or a row event whose event length header is smaller than the actual compressed payload.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/0adbb7fd5855fa0f. Report an issue: GitHub.