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
- 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.
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
- 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.
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
- No JsonCodec provider found. Please add json-common-core to
- The class 'org.apache.seata.serializer.protobuf.ProtobufSeri
- not found service provider for : {} caused by {}
- not found service provider for : {}
- Extension instance(definition: {}, class: {}) could not be
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/36244cb96ba35f54.
Report an issue: GitHub.