apache/incubator-seata · error · IllegalArgumentException
Unknown BranchType[{ordinal}]
Error message
Unknown BranchType[{ordinal}] What it means
BranchType.get(int) maps a numeric branch type from the protocol back to the BranchType enum (AT, XA, TCC, SAGA). It throws when the ordinal does not match any enum entry, meaning the decoded integer is not a branch type this build knows.
Source
Thrown at core/src/main/java/org/apache/seata/core/model/BranchType.java:73
* @return the branch type
*/
public static BranchType get(byte ordinal) {
return get((int) ordinal);
}
/**
* Get branch type.
*
* @param ordinal the ordinal
* @return the branch type
*/
public static BranchType get(int ordinal) {
for (BranchType branchType : values()) {
if (branchType.ordinal() == ordinal) {
return branchType;
}
}
throw new IllegalArgumentException("Unknown BranchType[" + ordinal + "]");
}
/**
* Get branch type.
*
* @param name the name
* @return the branch type
*/
public static BranchType get(String name) {
for (BranchType branchType : values()) {
if (branchType.name().equalsIgnoreCase(name)) {
return branchType;
}
}
throw new IllegalArgumentException("Unknown BranchType[" + name + "]");
}
}
View on GitHub (pinned to e01f97c6db)
Solutions
- Align Seata versions on both ends of the RPC connection.
- Ensure point-to-point TCP between RM/TM and TC — no HTTP-style proxies or middleboxes rewriting the stream.
- Enable protocol debug logs (org.apache.seata.rpc) and inspect the failing RpcMessage id/type to locate which message decodes badly.
Example fix
# before: mixed versions rm seata 1.4 -> tc seata 2.2 # after rm seata 2.2 -> tc seata 2.2
Defensive patterns
Strategy: type-guard
Validate before calling
static boolean validBranchOrdinal(int o) {
for (BranchType b : BranchType.values()) if (b.ordinal() == o) return true;
return false;
} Type guard
static Optional<BranchType> safeBranch(int o) {
return Arrays.stream(BranchType.values()).filter(b -> b.ordinal() == o).findFirst();
} Try / catch
catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unknown BranchType")) { closeChannelSafely(); LOG.warn("protocol mismatch: {}", e.getMessage()); }
else throw e;
} Prevention
- Version-check both ends at connect time
- Never expose the TC RPC port to non-Seata workloads
When it happens
Trigger: A branch register/undo message arrives carrying a branch-type byte outside 0..3 for this version, or protocol bytes are misaligned/corrupt so a different field is read as the branch type.
Common situations: Version skew (a future enum entry sent to an old build), non-Seata clients on the TC port, or framing corruption introduced by a TCP proxy that modifies the byte stream.
Related errors
- Unknown TransactionExceptionCode[{ordinal}]
- Unknown ResultCode[{ordinal}]
- Unknown ClientType[{ordinal}]
- Unknown GlobalStatus[{code}]
- Unknown BranchType[{ordinal}]
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/46c6bb755b6b6594.
Report an issue: GitHub.