{"record":{"id":"fee5bac226dfafb4","repo":"apache/incubator-seata","slug":"register-msg-is-null-role-s","errorCode":null,"errorMessage":"register msg is null, role:%s","messagePattern":"register msg is null, role:(.+?)","errorType":"exception","errorClass":"FrameworkException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/seata/core/rpc/netty/NettyPoolableFactory.java","lineNumber":63,"sourceCode":"     * @param rpcRemotingClient the rpc remoting client\n     */\n    public NettyPoolableFactory(AbstractNettyRemotingClient rpcRemotingClient, NettyClientBootstrap clientBootstrap) {\n        this.rpcRemotingClient = rpcRemotingClient;\n        this.clientBootstrap = clientBootstrap;\n    }\n\n    @Override\n    public Channel makeObject(NettyPoolKey key) {\n        InetSocketAddress address = NetUtil.toInetSocketAddress(key.getAddress());\n        if (LOGGER.isInfoEnabled()) {\n            LOGGER.info(\"NettyPool create channel to \" + key);\n        }\n        Channel tmpChannel = clientBootstrap.getNewChannel(address);\n        long start = System.currentTimeMillis();\n        Object response;\n        Channel channelToServer = null;\n        if (key.getMessage() == null) {\n            throw new FrameworkException(\n                    \"register msg is null, role:\" + key.getTransactionRole().name());\n        }\n        try {\n            response = rpcRemotingClient.sendSyncRequest(tmpChannel, key.getMessage());\n            if (!isRegisterSuccess(response, key.getTransactionRole())) {\n                rpcRemotingClient.onRegisterMsgFail(key.getAddress(), tmpChannel, response, key.getMessage());\n            } else {\n                channelToServer = tmpChannel;\n                rpcRemotingClient.onRegisterMsgSuccess(key.getAddress(), tmpChannel, response, key.getMessage());\n            }\n        } catch (Exception exx) {\n            if (tmpChannel != null) {\n                tmpChannel.close();\n            }\n            throw new FrameworkException(\n                    \"register \" + key.getTransactionRole().name() + \" error, errMsg:\" + exx.getMessage());\n        }\n        if (LOGGER.isInfoEnabled()) {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/core/src/main/java/org/apache/seata/core/rpc/netty/NettyPoolableFactory.java#L45-L81","documentation":"FrameworkException from NettyPoolableFactory.makeObject: the pooled-channel key carried no register message. When the client borrows a channel from the pool, the pool key must contain the RegisterTMRequest/RegisterRMRequest that is sent immediately after connect; a null message means the key was built without its register request, which is an internal invariant violation rather than a network problem.","triggerScenarios":" poolKeyFunction.apply(address) returning a NettyPoolKey whose message field is null when the pool creates the object — e.g. a custom or misconfigured client bootstrap path that constructs keys without the register request, or internal state where the register message was not yet initialized when reconnect kicked in.","commonSituations":"Rare in stock deployments; seen with custom client subclasses/forks that override the pool key factory; races during very early startup where reconnect fires before the register message is prepared; version skew in internal APIs after partial upgrades.","solutions":["Do not construct NettyPoolKey without the register request: use the client's built-in poolKeyFunction (AbstractNettyRemotingClient builds it with RegisterRMRequest/RegisterTMRequest)","If subclassing, ensure getPoolKeyFunction supplies the register message for every address","Upgrade to a coherent seata version across all modules — mixed versions can break internal key contracts","As a workaround, restart the client so keys are rebuilt with their register messages"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"NettyPoolKey key = poolKeyFunction.apply(address);\nif (key == null || key.getMessage() == null) {\n    throw new IllegalStateException(\"pool key missing register message for \" + address);\n}","typeGuard":"boolean poolKeyHasRegisterMsg(NettyPoolKey key) {\n    return key != null && key.getMessage() != null;\n}","tryCatchPattern":"catch (FrameworkException e) {\n    if (e.getMessage().startsWith(\"register msg is null\")) {\n        // internal misconfiguration: rebuild keys via built-in poolKeyFunction; restart client\n    }\n}","preventionTips":["Use the stock pool key factories; do not construct NettyPoolKey without a register request","Keep all seata modules on one version","Restart the client to rebuild keys if seen after partial upgrades"],"tags":["registration","pool","internal","client"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}