apache/incubator-seata · critical · IllegalArgumentException

No serializer found

Error message

No serializer found

What it means

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.

Source

Thrown at core/src/main/java/org/apache/seata/core/rpc/netty/v1/ProtocolDecoderV1.java:81

 * @since 0.7.0
 */
public class ProtocolDecoderV1 extends LengthFieldBasedFrameDecoder implements ProtocolDecoder {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolDecoderV1.class);
    private final List<SerializerType> supportDeSerializerTypes;

    public ProtocolDecoderV1() {
        /*
        int maxFrameLength,
        int lengthFieldOffset,  magic code is 2B, and version is 1B, and then FullLength. so value is 3
        int lengthFieldLength,  FullLength is int(4B). so values is 4
        int lengthAdjustment,   FullLength include all data and read 7 bytes before, so the left length is (FullLength-7). so values is -7
        int initialBytesToStrip we will check magic code and version self, so do not strip any bytes. so values is 0
        */
        super(ProtocolConstants.MAX_FRAME_LENGTH, 3, 4, -7, 0);
        supportDeSerializerTypes = SerializerServiceLoader.getSupportedSerializers();
        if (supportDeSerializerTypes.isEmpty()) {
            throw new IllegalArgumentException("No serializer found");
        }
    }

    @Override
    public RpcMessage decodeFrame(ByteBuf frame) {
        byte b0 = frame.readByte();
        byte b1 = frame.readByte();
        if (ProtocolConstants.MAGIC_CODE_BYTES[0] != b0 || ProtocolConstants.MAGIC_CODE_BYTES[1] != b1) {
            throw new IllegalArgumentException("Unknown magic code: " + b0 + ", " + b1);
        }

        byte version = frame.readByte();

        int fullLength = frame.readInt();
        short headLength = frame.readShort();
        byte messageType = frame.readByte();
        byte codecType = frame.readByte();
        byte compressorType = frame.readByte();

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Add the default serializer module back: `org.apache.seata:seata-serializer-seata` (match your Seata version).
  2. Run `jar tf <yourjar> | grep 'META-INF/services'` (or unpack) to confirm the Serializer SPI file survived shading; add ServicesResourceTransformer to the shade plugin.
  3. If you intentionally use protobuf/kryo serialization, add `seata-serializer-protobuf` or the matching module so the SPI list is non-empty.
  4. Check for duplicate/conflicting Seata versions on the classpath that can break SPI resolution.

Example fix

<!-- before -->
<dependency>
  <groupId>org.apache.seata</groupId>
  <artifactId>seata-all</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.apache.seata</groupId>
      <artifactId>seata-serializer-seata</artifactId> <!-- -> No serializer found -->
    </exclusion>
  </exclusions>
</dependency>

<!-- after: remove the exclusion, or add explicitly -->
<dependency>
  <groupId>org.apache.seata</groupId>
  <artifactId>seata-serializer-seata</artifactId>
  <version>${seata.version}</version>
</dependency>
Defensive patterns

Strategy: validation

Validate before calling

// fail fast at app startup instead of at first RPC decode
if (org.apache.seata.core.serializer.SerializerServiceLoader.getSupportedSerializers().isEmpty()) {
    throw new IllegalStateException(
        "No Seata serializer on classpath - add org.apache.seata:seata-serializer-seata");
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/36244cb96ba35f54. Report an issue: GitHub.