{"record":{"id":"7039403a516d92e7","repo":"apache/incubator-seata","slug":"unknown-transactionexceptioncode-ordinal-703940","errorCode":null,"errorMessage":"Unknown TransactionExceptionCode[{ordinal}]","messagePattern":"Unknown TransactionExceptionCode\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/seata/core/exception/TransactionExceptionCode.java","lineNumber":170,"sourceCode":"     * @param ordinal the ordinal\n     * @return the transaction exception code\n     */\n    public static TransactionExceptionCode get(byte ordinal) {\n        return get((int) ordinal);\n    }\n\n    /**\n     * Get transaction exception code.\n     *\n     * @param ordinal the ordinal\n     * @return the transaction exception code\n     */\n    public static TransactionExceptionCode get(int ordinal) {\n        TransactionExceptionCode value = null;\n        try {\n            value = TransactionExceptionCode.values()[ordinal];\n        } catch (Exception e) {\n            throw new IllegalArgumentException(\"Unknown TransactionExceptionCode[\" + ordinal + \"]\");\n        }\n        return value;\n    }\n}\n","sourceCodeStart":152,"sourceCodeEnd":175,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/core/src/main/java/org/apache/seata/core/exception/TransactionExceptionCode.java#L152-L175","documentation":"TransactionExceptionCode.get(int) maps a numeric code from the wire protocol back to the TransactionExceptionCode enum (e.g. BeginFailed, LockKeyConflict, IoErro). It throws when the ordinal is outside the enum range — either negative or >= values().length — i.e. the integer in the message header cannot be a valid exception code on this build.","triggerScenarios":"Decoding a TransactionExceptionCode from an RPC message sent by a peer with a different (usually newer) enum that has more codes, or from a corrupted/garbage frame where random bytes land in the code field.","commonSituations":"Version skew during rolling upgrades (newer TC sends a code the old client enum lacks), non-Seata traffic hitting the TC service port, or a proxy/load balancer corrupting the binary protocol.","solutions":["Pin client and server to the same (or compatible) Seata version; upgrade the older side first during rolling upgrades.","Verify only Seata nodes connect to the TC port; keep binary RPC traffic off HTTP proxies.","Capture the frame (packet dump / debug logging of RpcMessage) to confirm whether the code field is genuinely newer or the payload is corrupt."],"exampleFix":"# before\nclient seata 1.5 <-> server seata 2.x (new codes)\n# after\nclient upgraded to match server major.minor","handlingStrategy":"type-guard","validationCode":"static boolean validTxExceptionCode(int ordinal) {\n    return ordinal >= 0 && ordinal < TransactionExceptionCode.values().length;\n}","typeGuard":"static Optional<TransactionExceptionCode> safeGet(int o) {\n    return (o >= 0 && o < TransactionExceptionCode.values().length)\n        ? Optional.of(TransactionExceptionCode.values()[o]) : Optional.empty();\n}","tryCatchPattern":"catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"Unknown TransactionExceptionCode\")) {\n        LOG.warn(\"peer may run newer seata; code={}\", ordinal);\n        // degrade: treat as generic TransactionException instead of killing the channel\n    }\n}","preventionTips":["Gate connections on compatible version ranges during upgrades","Log peer version at handshake to correlate later unknown-code errors"],"tags":["protocol","enum","version-mismatch","decode"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}