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

  1. Add the dependency: `org.apache.seata:seata-serializer-protobuf` with the same version as the rest of Seata.
  2. Restart the JVM after adding it — the presence check is static and only re-evaluated on class reload.
  3. If protobuf was set by mistake, change serialization back to seata (the default) and no extra jar is needed.
  4. 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

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


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