apache/incubator-seata · error · UnsupportedOperationException
Unsupported version: {version}
Error message
Unsupported version: {version} What it means
Thrown by MultiProtocolDecoder when an inbound frame's protocol version byte maps to no registered ProtocolDecoder/ProtocolEncoder pair. Seata's multi-protocol support keeps per-version codecs; a version that is neither in the map (and not clamped to maxCurrentVersion because it was below the minimum or simply absent) hits this branch and the pipeline for that channel cannot be installed.
Source
Thrown at core/src/main/java/org/apache/seata/core/rpc/netty/MultiProtocolDecoder.java:143
version = decideVersion(decoded);
}
if (decoded instanceof ByteBuf) {
frame = (ByteBuf) decoded;
// Ensure version is within supported range
if (version > maxCurrentVersion) {
version = maxCurrentVersion;
LOGGER.error(
"Detected version {} is greater than max supported version {}, using max supported version.",
version,
maxCurrentVersion);
}
ProtocolDecoder decoder = protocolDecoderMap.get(version);
ProtocolEncoder encoder = protocolEncoderMap.get(version);
try {
if (decoder == null || encoder == null) {
throw new UnsupportedOperationException("Unsupported version: " + version);
}
return decoder.decodeFrame(frame);
} finally {
if (version != ProtocolConstants.VERSION_0) {
frame.release();
}
// Remove existing encoder if it exists (for client-side compatibility)
removeExistingEncoder(ctx, encoder);
ctx.pipeline().addLast((ChannelHandler) decoder);
ctx.pipeline().addLast((ChannelHandler) encoder);
if (channelHandlers != null) {
ctx.pipeline().addLast(channelHandlers);
}
ctx.pipeline().remove(this);
}
}
} catch (Exception exx) {
LOGGER.error("Decode frame error, cause: {}", exx.getMessage());View on GitHub (pinned to e01f97c6db)
Solutions
- Align seata client and server versions (same minor release line on both ends)
- If you intentionally run mixed versions, check which protocol versions both builds register in MultiProtocolDecoder and pick one both support
- Inspect the first bytes of the frame (magic code + version) with a wire capture if frames may be corrupted or proxied by something that rewrites bytes
- Set the protocol explicitly (seata.client.protocol / seata.server.protocol) rather than relying on negotiation
Example fix
# before: mismatched versions client: org.apache.seata:seata-all:2.1.0 server: seataio/seata-server:1.7.0 # after client: org.apache.seata:seata-all:2.1.0 server: seataio/seata-server:2.1.0
Defensive patterns
Strategy: validation
Validate before calling
// before connecting, confirm version compatibility int v = ProtocolConstants.CURRENT_VERSION; // what this build supports // ensure client and server manifests declare the same seata version
Try / catch
catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Unsupported version")) {
// abort connection: version skew; pin matching versions and restart
}
} Prevention
- Pin identical seata versions on client and server (dependencyManagement)
- Add a startup banner/log of negotiated protocol version to catch skew early
- Run contract tests across versions before upgrading one side
When it happens
Trigger: A client connecting with a protocol version the server build does not carry a codec for — typically a newer client talking to an older server where the version byte is lower than the server's minimum supported (so the max-version clamp does not apply), or a custom protocol version registered on one side only.
Common situations: Version skew between seata client and server (e.g. client 2.x vs server 1.x); custom transport protocol extensions deployed only to the server or only to the client; corrupted frames shifting the version byte.
Related errors
- Invalid event format: expected prefix '{}', got: {}
- Unknown GlobalStatus[{code}]
- unknown codec:{code}
- Unknown TransactionExceptionCode[{ordinal}]
- Unknown ResultCode[{ordinal}]
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/f6242eacddc31819.
Report an issue: GitHub.