{"record":{"id":"a7322ed27503f630","repo":"alibaba/canal","slug":"deserializer-failed-by-e-getmessage","errorCode":null,"errorMessage":"deserializer failed by ${e.getMessage()}","messagePattern":"deserializer failed by (.+?)","errorType":"exception","errorClass":"CanalClientException","httpStatus":null,"severity":"error","filePath":"connector/core/src/main/java/com/alibaba/otter/canal/connector/core/util/CanalMessageSerializerUtil.java","lineNumber":128,"sourceCode":"                        } else {\n                            for (ByteString byteString : messages.getMessagesList()) {\n                                result.addEntry(CanalEntry.Entry.parseFrom(byteString));\n                            }\n                            result.setRaw(false);\n                        }\n                        return result;\n                    }\n                    case ACK: {\n                        CanalPacket.Ack ack = CanalPacket.Ack.parseFrom(p.getBody());\n                        throw new CanalClientException(\"something goes wrong with reason: \" + ack.getErrorMessage());\n                    }\n                    default: {\n                        throw new CanalClientException(\"unexpected packet type: \" + p.getType());\n                    }\n                }\n            }\n        } catch (Exception e) {\n            throw new CanalClientException(\"deserializer failed by \" + e.getMessage(), e);\n        }\n    }\n}\n","sourceCodeStart":110,"sourceCodeEnd":132,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/connector/core/src/main/java/com/alibaba/otter/canal/connector/core/util/CanalMessageSerializerUtil.java#L110-L132","documentation":"This is the outer catch-all in CanalMessageSerializerUtil.deserializer: any Exception raised while parsing the Packet/Messages/Entry (including the inner unexpected-packet-type and ACK errors) is rewrapped as a CanalClientException with this prefix and the original cause chained. It surfaces as the single failure point for all malformed or unsupported canal message bytes.","triggerScenarios":"Any exception inside deserializer(): com.google.protobuf.InvalidProtocolBufferException from CanalPacket.Packet.parseFrom / Messages.parseFrom / Entry.parseFrom on truncated or non-protobuf data; the compression-not-supported CanalClientException; the unexpected-packet-type CanalClientException; or the ACK CanalClientException. All are caught at line 127 and rethrown with this message.","commonSituations":"Truncated message from the broker (network drop, partial serialization); bytes that are valid protobuf but not a CanalPacket; a flatMessage JSON payload mistakenly passed to the protobuf deserializer; partial write where only some of a multi-part message arrived.","solutions":["Read the chained cause (CanalClientException.getCause()) — it carries the real failure (InvalidProtocolBufferException, ACK error, unexpected type) and points to the precise fix.","If the cause is InvalidProtocolBufferException, verify the byte[] was produced by CanalMessageSerializerUtil.serializer and was not truncated in transit.","If the cause is the ACK error, inspect the upstream canal server / producer for the ack.getErrorMessage() reason.","If flatMessage mode is enabled on the producer, parse the payload as JSON (JSON.parseObject(data, CommonMessage.class)) instead of calling the protobuf deserializer."],"exampleFix":"// before\ntry {\n    Message msg = CanalMessageSerializerUtil.deserializer(data);\n} catch (CanalClientException e) {\n    // only sees 'deserializer failed by ...'\n}\n\n// after — unwrap the real cause to diagnose\ntry {\n    Message msg = CanalMessageSerializerUtil.deserializer(data);\n} catch (CanalClientException e) {\n    Throwable cause = e.getCause();\n    log.error(\"deserialize failed, rootCause={}, msg={}\",\n        cause == null ? \"unknown\" : cause.getClass().getSimpleName(), e.getMessage());\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    Message msg = CanalMessageSerializerUtil.deserializer(data);\n} catch (CanalClientException e) {\n    Throwable root = e.getCause();\n    // branch on root: InvalidProtocolBufferException vs ACK vs unexpected-type\n    log.error(\"deserialize failed root={}\", root == null ? \"none\" : root.getClass().getName(), e);\n    throw e;\n}","preventionTips":["Always inspect getCause() — the 'deserializer failed by' prefix hides the real failure.","For flatMessage producers, parse JSON instead of using the protobuf deserializer.","Validate message integrity at the broker/consumer boundary before deserialization."],"tags":["protobuf","serialization","canal-connector","diagnostics"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}