apache/incubator-seata · error · IllegalArgumentException

Unknown TransactionExceptionCode[{ordinal}]

Error message

Unknown TransactionExceptionCode[{ordinal}]

What it means

Compatible-layer (io.seata) mirror of TransactionExceptionCode.get: it maps an ordinal back to the enum and throws IllegalArgumentException when the ordinal is out of range. This runs when legacy io.seata API objects convert wire/DB codes into typed exception codes.

Source

Thrown at compatible/src/main/java/io/seata/core/exception/TransactionExceptionCode.java:167

     * @param ordinal the ordinal
     * @return the transaction exception code
     */
    public static TransactionExceptionCode get(byte ordinal) {
        return get((int) ordinal);
    }

    /**
     * Get transaction exception code.
     *
     * @param ordinal the ordinal
     * @return the transaction exception code
     */
    public static TransactionExceptionCode get(int ordinal) {
        TransactionExceptionCode value = null;
        try {
            value = TransactionExceptionCode.values()[ordinal];
        } catch (Exception e) {
            throw new IllegalArgumentException("Unknown TransactionExceptionCode[" + ordinal + "]");
        }
        return value;
    }

    public org.apache.seata.core.exception.TransactionExceptionCode convertTransactionExceptionCode() {
        return org.apache.seata.core.exception.TransactionExceptionCode.get(this.ordinal());
    }
}

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Align the compatible module version with the Seata client/server version in use.
  2. Log the offending ordinal and compare to the enum constants on both sides to find the skew.
  3. Prefer the org.apache.seata API directly for new code so the compatibility conversion path is not exercised.
  4. Range-check ordinals against values().length before calling get().

Example fix

// before
TransactionExceptionCode code = TransactionExceptionCode.get(ordinal);

// after
TransactionExceptionCode[] all = TransactionExceptionCode.values();
if (ordinal < 0 || ordinal >= all.length) {
    throw new IllegalArgumentException("Unsupported exception code from peer: " + ordinal);
}
TransactionExceptionCode code = all[ordinal];
Defensive patterns

Strategy: validation

Validate before calling

boolean isKnownTxExceptionCode(int ordinal) {
    TransactionExceptionCode[] all = TransactionExceptionCode.values();
    return ordinal >= 0 && ordinal < all.length;
}

Try / catch

try {
    return TransactionExceptionCode.get(ordinal);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("exception code " + ordinal + " unknown; check seata version alignment", e);
}

Prevention

When it happens

Trigger: Calling TransactionExceptionCode.get(ordinal) with an int not matching any enum constant ordinal — typically during unwrap/convert of an io.seata exception payload whose code was produced by a different (newer or older) build.

Common situations: Applications mixing the old io.seata (compatible) artifacts with newer org.apache.seata clients/servers on the classpath or across the wire; deserializing codes persisted by another version; test fixtures using fabricated ordinals.

Related errors


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