{"record":{"id":"36244cb96ba35f54","repo":"apache/incubator-seata","slug":"no-serializer-found","errorCode":null,"errorMessage":"No serializer found","messagePattern":"No serializer found","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"core/src/main/java/org/apache/seata/core/rpc/netty/v1/ProtocolDecoderV1.java","lineNumber":81,"sourceCode":" * @since 0.7.0\n */\npublic class ProtocolDecoderV1 extends LengthFieldBasedFrameDecoder implements ProtocolDecoder {\n\n    private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolDecoderV1.class);\n    private final List<SerializerType> supportDeSerializerTypes;\n\n    public ProtocolDecoderV1() {\n        /*\n        int maxFrameLength,\n        int lengthFieldOffset,  magic code is 2B, and version is 1B, and then FullLength. so value is 3\n        int lengthFieldLength,  FullLength is int(4B). so values is 4\n        int lengthAdjustment,   FullLength include all data and read 7 bytes before, so the left length is (FullLength-7). so values is -7\n        int initialBytesToStrip we will check magic code and version self, so do not strip any bytes. so values is 0\n        */\n        super(ProtocolConstants.MAX_FRAME_LENGTH, 3, 4, -7, 0);\n        supportDeSerializerTypes = SerializerServiceLoader.getSupportedSerializers();\n        if (supportDeSerializerTypes.isEmpty()) {\n            throw new IllegalArgumentException(\"No serializer found\");\n        }\n    }\n\n    @Override\n    public RpcMessage decodeFrame(ByteBuf frame) {\n        byte b0 = frame.readByte();\n        byte b1 = frame.readByte();\n        if (ProtocolConstants.MAGIC_CODE_BYTES[0] != b0 || ProtocolConstants.MAGIC_CODE_BYTES[1] != b1) {\n            throw new IllegalArgumentException(\"Unknown magic code: \" + b0 + \", \" + b1);\n        }\n\n        byte version = frame.readByte();\n\n        int fullLength = frame.readInt();\n        short headLength = frame.readShort();\n        byte messageType = frame.readByte();\n        byte codecType = frame.readByte();\n        byte compressorType = frame.readByte();","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/core/src/main/java/org/apache/seata/core/rpc/netty/v1/ProtocolDecoderV1.java#L63-L99","documentation":"ProtocolDecoderV1's constructor asks SerializerServiceLoader.getSupportedSerializers() for all SPI-registered serializers; if the list comes back empty it throws IllegalArgumentException('No serializer found'). It means the classpath contains no Seata serializer implementation at all, so the RPC frame decoder cannot be constructed and the Netty pipeline setup fails.","triggerScenarios":"Constructing ProtocolDecoderV1 when no org.apache.seata.core.serializer.Serializer SPI implementation is on the classpath — i.e. seata-serializer-seata (the default SEATA serializer) was excluded from dependencies while nothing else (e.g. seata-serializer-protobuf, kryo) replaces it. Typical after dependency pruning or shading the client incorrectly.","commonSituations":"Maven/Gradle exclusion of seata-serializer-* to slim a fat jar; a broken shade/assembly that drops META-INF/services entries; using a bom that pins seata-all but explicitly excluding the serializer module; OSGi/classloader isolation hiding the SPI files.","solutions":["Add the default serializer module back: `org.apache.seata:seata-serializer-seata` (match your Seata version).","Run `jar tf <yourjar> | grep 'META-INF/services'` (or unpack) to confirm the Serializer SPI file survived shading; add ServicesResourceTransformer to the shade plugin.","If you intentionally use protobuf/kryo serialization, add `seata-serializer-protobuf` or the matching module so the SPI list is non-empty.","Check for duplicate/conflicting Seata versions on the classpath that can break SPI resolution."],"exampleFix":"<!-- before -->\n<dependency>\n  <groupId>org.apache.seata</groupId>\n  <artifactId>seata-all</artifactId>\n  <exclusions>\n    <exclusion>\n      <groupId>org.apache.seata</groupId>\n      <artifactId>seata-serializer-seata</artifactId> <!-- -> No serializer found -->\n    </exclusion>\n  </exclusions>\n</dependency>\n\n<!-- after: remove the exclusion, or add explicitly -->\n<dependency>\n  <groupId>org.apache.seata</groupId>\n  <artifactId>seata-serializer-seata</artifactId>\n  <version>${seata.version}</version>\n</dependency>","handlingStrategy":"validation","validationCode":"// fail fast at app startup instead of at first RPC decode\nif (org.apache.seata.core.serializer.SerializerServiceLoader.getSupportedSerializers().isEmpty()) {\n    throw new IllegalStateException(\n        \"No Seata serializer on classpath - add org.apache.seata:seata-serializer-seata\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep seata-serializer-seata as an explicit (non-excluded) dependency next to seata-all.","When using maven-shade, add ServicesResourceTransformer so META-INF/services files merge.","Add a startup assertion that at least one serializer SPI is discoverable."],"tags":["serialization","spi","classpath","dependency","decoder"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}