apache/incubator-seata · error · EnhancedServiceNotFoundException
The class 'org.apache.seata.serializer.protobuf.ProtobufSeri
Error message
The class 'org.apache.seata.serializer.protobuf.ProtobufSerializer' not found. Please manually reference 'org.apache.seata:seata-serializer-protobuf' dependency.
What it means
SerializerServiceLoader.load(SerializerType, byte) throws EnhancedServiceNotFoundException when serialization type PROTOBUF is requested but the optional ProtobufSerializer class is not on the classpath (a cheap ReflectionUtil.isClassPresent check up front). Seata ships protobuf serialization as an optional module, so this error is a friendly directive to add the dependency rather than a real service-loading failure.
Source
Thrown at core/src/main/java/org/apache/seata/core/serializer/SerializerServiceLoader.java:82
private SerializerServiceLoader() {}
private static final String PROTOBUF_SERIALIZER_CLASS_NAME =
"org.apache.seata.serializer.protobuf.ProtobufSerializer";
private static final boolean CONTAINS_PROTOBUF_DEPENDENCY =
ReflectionUtil.isClassPresent(PROTOBUF_SERIALIZER_CLASS_NAME);
/**
* Load the service of {@link Serializer}
*
* @param type the serializer type
* @return the service of {@link Serializer}
* @throws EnhancedServiceNotFoundException the enhanced service not found exception
*/
public static Serializer load(SerializerType type, byte version) throws EnhancedServiceNotFoundException {
// The following code is only used to kindly prompt users to add missing dependencies.
if (type == SerializerType.PROTOBUF && !CONTAINS_PROTOBUF_DEPENDENCY) {
throw new EnhancedServiceNotFoundException("The class '" + PROTOBUF_SERIALIZER_CLASS_NAME + "' not found. "
+ "Please manually reference 'org.apache.seata:seata-serializer-protobuf' dependency.");
}
String serializerName = serializerKey(type, version);
String resolvedSerializerName = resolveSerializerName(serializerName);
if (!Objects.equals(serializerName, resolvedSerializerName)) {
LOGGER.info(
"Since {} is no longer maintained, This serialization extension has been replaced with {}.",
serializerName,
resolvedSerializerName);
}
Serializer serializer = SERIALIZER_MAP.get(resolvedSerializerName);
if (serializer == null) {
if (type == SerializerType.SEATA) {
serializer = EnhancedServiceLoader.load(Serializer.class, type.name(), new Object[] {version});
} else {
serializer = EnhancedServiceLoader.load(Serializer.class, resolvedSerializerName);
}View on GitHub (pinned to e01f97c6db)
Solutions
- Add the dependency: `org.apache.seata:seata-serializer-protobuf` with the same version as the rest of Seata.
- Restart the JVM after adding it — the presence check is static and only re-evaluated on class reload.
- If protobuf was set by mistake, change serialization back to seata (the default) and no extra jar is needed.
- Verify with `ReflectionUtil.isClassPresent("org.apache.seata.serializer.protobuf.ProtobufSerializer")` in your environment if unsure.
Example fix
<!-- before -->
<dependency>
<groupId>org.apache.seata</groupId>
<artifactId>seata-all</artifactId>
</dependency>
<!-- serialization=protobuf in config -> EnhancedServiceNotFoundException -->
<!-- after -->
<dependency>
<groupId>org.apache.seata</groupId>
<artifactId>seata-serializer-protobuf</artifactId>
<version>${seata.version}</version>
</dependency> Defensive patterns
Strategy: validation
Validate before calling
// before selecting protobuf serialization
if (serializationType == SerializerType.PROTOBUF
&& !io.seata.common.util.ReflectionUtil.isClassPresent("org.apache.seata.serializer.protobuf.ProtobufSerializer")) {
throw new IllegalStateException(
"serialization=protobuf requires the optional dependency org.apache.seata:seata-serializer-protobuf");
}
Serializer s = SerializerServiceLoader.load(serializationType, version); Try / catch
try {
return SerializerServiceLoader.load(type, version);
} catch (EnhancedServiceNotFoundException e) {
if (e.getMessage().contains("seata-serializer-protobuf")) {
// dependency problem: degrade to default SEATA serializer if acceptable, else rethrow
return SerializerServiceLoader.load(SerializerType.SEATA, version);
}
throw e;
} Prevention
- Add seata-serializer-protobuf in the same commit that flips serialization to protobuf.
- Grep your builds for exclusions of seata-serializer-* modules.
- Document in the project README which serialization each service uses.
When it happens
Trigger: Configuring seata.client/serialization (or server serialization) to protobuf via SerializerType.PROTOBUF and calling SerializerServiceLoader.load(...) — e.g. during client init, channel handler setup, or server codec bootstrap — without org.apache.seata:seata-serializer-protobuf in the dependencies.
Common situations: Setting serialization=protobuf after copying config from a project that had the extra jar; upgrading Seata and forgetting the previously-manual protobuf module; using seata-all (which does not bundle the protobuf serializer) and assuming all codecs are included.
Related errors
- No serializer found
- No JsonCodec provider found. Please add json-common-core to
- not found service provider for : {}
- Invalid port number in: {}
- Invalid format for endpoint: {}
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/4ba8a9b522501bb9.
Report an issue: GitHub.