alibaba/canal · error · CanalClientException

compression is not supported in this connector

Error message

compression is not supported in this connector

What it means

Thrown by CanalMessageSerializerUtil.deserializer when a parsed CanalPacket.Packet reports a Compression value other than NONE or COMPRESSIONCOMPATIBLEPROTO2. The canal client connector does not implement payload decompression, so any non-NONE compression flag is rejected outright (it then gets wrapped by the outer catch into 'deserializer failed by ...').

Solutions

  1. Align canal server and client connector versions so both treat Compression as NONE.
  2. Ensure the byte[] passed to deserializer is a genuine canal Packet produced by CanalMessageSerializerUtil.serializer (not a foreign payload).
  3. Disable any compression flag on the producer side (canal protocol uses NONE).

Example fix

// before
byte[] payload = readFromForeignSource();
deserializer(payload, false);  // unsupported compression
// after
byte[] payload = readFromCanalProducer();
deserializer(payload, false);  // Compression == NONE
Defensive patterns

Strategy: validation

Validate before calling

// Inspect packet type/compression before deserializing as MESSAGES
CanalPacket.Packet p = CanalPacket.Packet.parseFrom(data);
if (!CanalPacket.Compression.NONE.equals(p.getCompression())
    && !CanalPacket.Compression.COMPRESSIONCOMPATIBLEPROTO2.equals(p.getCompression())) {
    throw new CanalClientException("unsupported compression: " + p.getCompression());
}
if (p.getType() != CanalPacket.PacketType.MESSAGES) {
    throw new CanalClientException("not a MESSAGES packet: " + p.getType());
}

Type guard

boolean isDecompressible(CanalPacket.Packet p) {
    return p.getCompression().equals(CanalPacket.Compression.NONE)
        || p.getCompression().equals(CanalPacket.Compression.COMPRESSIONCOMPATIBLEPROTO2);
}

Try / catch

try {
    Message m = CanalMessageSerializerUtil.deserializer(data, lazyParse);
} catch (CanalClientException e) {
    if (e.getMessage().contains("compression is not supported")) {
        // version mismatch: align canal server and client versions
    } else throw e;
}

Prevention

When it happens

Trigger: Receiving a packet whose Compression field is set to a compressed mode; producer/sender and consumer running different canal protocol versions where one side sets compression the other cannot decode; corrupted bytes being misparsed as a Packet with a stray compression enum value.

Common situations: Version mismatch between canal server (producer) and client connector (consumer) introducing a compression flag; cross-system interoperability where a non-canal sender populates the Compression field; truncated/corrupt byte array parsed into a bogus Packet.

Related errors


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

Appendix: source

Thrown at connector/core/src/main/java/com/alibaba/otter/canal/connector/core/util/CanalMessageSerializerUtil.java:101

        }
        return null;
    }

    public static Message deserializer(byte[] data) {
        return deserializer(data, false);
    }

    public static Message deserializer(byte[] data, boolean lazyParseEntry) {
        try {
            if (data == null) {
                return null;
            } else {
                CanalPacket.Packet p = CanalPacket.Packet.parseFrom(data);
                switch (p.getType()) {
                    case MESSAGES: {
                        if (!p.getCompression().equals(CanalPacket.Compression.NONE)
                            && !p.getCompression().equals(CanalPacket.Compression.COMPRESSIONCOMPATIBLEPROTO2)) {
                            throw new CanalClientException("compression is not supported in this connector");
                        }

                        CanalPacket.Messages messages = CanalPacket.Messages.parseFrom(p.getBody());
                        Message result = new Message(messages.getBatchId());
                        if (lazyParseEntry) {
                            // byteString
                            result.setRawEntries(messages.getMessagesList());
                            result.setRaw(true);
                        } else {
                            for (ByteString byteString : messages.getMessagesList()) {
                                result.addEntry(CanalEntry.Entry.parseFrom(byteString));
                            }
                            result.setRaw(false);
                        }
                        return result;
                    }
                    case ACK: {
                        CanalPacket.Ack ack = CanalPacket.Ack.parseFrom(p.getBody());

View on GitHub (pinned to 87be50e876)