{"record":{"id":"4eec46d8599125d8","repo":"apache/incubator-seata","slug":"register-rm-failed-client-version-s-server-vers","errorCode":null,"errorMessage":"register RM failed. client version: %s,server version: %s, errorMsg: %s, channel: %s","messagePattern":"register RM failed\\. client version: (.+?),server version: (.+?), errorMsg: (.+?), channel: (.+?)","errorType":"exception","errorClass":"FrameworkException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/seata/core/rpc/netty/RmNettyRemotingClient.java","lineNumber":241,"sourceCode":"        getClientChannelManager().registerChannel(serverAddress, channel, registerRMRequest.getVersion());\n        getClientChannelManager().putServerVersion(serverAddress, registerRMResponse.getVersion());\n        String dbKey = getMergedResourceKeys();\n        if (registerRMRequest.getResourceIds() != null) {\n            if (!registerRMRequest.getResourceIds().equals(dbKey)) {\n                sendRegisterMessage(serverAddress, channel, dbKey);\n            }\n        }\n    }\n\n    @Override\n    public void onRegisterMsgFail(\n            String serverAddress, Channel channel, Object response, AbstractMessage requestMessage) {\n        RegisterRMRequest registerRMRequest = (RegisterRMRequest) requestMessage;\n        RegisterRMResponse registerRMResponse = (RegisterRMResponse) response;\n        String errMsg = String.format(\n                \"register RM failed. client version: %s,server version: %s, errorMsg: %s, \" + \"channel: %s\",\n                registerRMRequest.getVersion(), registerRMResponse.getVersion(), registerRMResponse.getMsg(), channel);\n        throw new FrameworkException(errMsg);\n    }\n\n    /**\n     * Register new db key.\n     *\n     * @param resourceGroupId the resource group id\n     * @param resourceId      the db key\n     */\n    public void registerResource(String resourceGroupId, String resourceId) {\n\n        // Resource registration cannot be performed until the RM client is initialized\n        if (StringUtils.isBlank(transactionServiceGroup)) {\n            return;\n        }\n\n        // ResourceId can not be null or empty\n        if (StringUtils.isBlank(resourceId)) {\n            LOGGER.warn(\"The resourceId must not be null or empty when registering the RM client.\");","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/core/src/main/java/org/apache/seata/core/rpc/netty/RmNettyRemotingClient.java#L223-L259","documentation":"Thrown from RmNettyRemotingClient.onRegisterMsgFail: the Seata Server returned a failure RegisterRMResponse for the client's resource-manager registration request. The message records client version, server version, the server's errorMsg, and the channel, then wraps everything in a FrameworkException. It means the server actively rejected the RM (not a network failure).","triggerScenarios":"Client sends RegisterRMRequest during initResources/registerResource; server replies with a response whose result is not success (e.g. version check rejection, transaction group not hosted by this server, server-side validation failure). The callback onRegisterMsgFail fires and throws FrameworkException.","commonSituations":"transaction group (txServiceGroup) not present in the server's service.vgroupMapping config, so the server rejects the RM; client/server major version mismatch (e.g. old io.seata client against apache/seata 2.x server); connecting to a server that has not loaded the vgroup mapping; garbled registry data routing the client to the wrong cluster.","solutions":["Check server log at the same timestamp — the server-side errorMsg included in the message says exactly why it refused (e.g. 'invalid transaction group').","Align service.vgroupMapping.<group>=<cluster> in the server config with the client's txServiceGroup so the server recognizes the group.","Match client and server versions (upgrade old io.seata clients to org.apache.seata of the same line as the server).","Verify the client resolved the right server via registry (registry address, namespace, cluster) and is not hitting a server from another environment."],"exampleFix":"// before: client\nRMClient.init(appId, \"my_tx_group\");  // server has no mapping -> register RM failed\n\n# server application.yml\n# (missing)\n\n// after\n# server application.yml\nseata:\n  service:\n    vgroupMapping:\n      my_tx_group: \"default\"\n\n// client\nRMClient.init(appId, \"my_tx_group\");  // now registers successfully","handlingStrategy":"validation","validationCode":"// client side: fail fast before RMClient.init if the group has no server mapping\nString group = \"my_tx_group\";\nList<String> avail = io.seata.discovery.registry.RegistryFactory.getInstance().lookup(group);\nif (avail == null || avail.isEmpty()) {\n    throw new IllegalStateException(\"No seata server found for txServiceGroup \" + group + \" - fix service.vgroupMapping\");\n}\nRMClient.init(applicationId, group);","typeGuard":null,"tryCatchPattern":"try {\n    RMClient.init(applicationId, txServiceGroup);\n} catch (io.seata.common.exception.FrameworkException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"register RM failed\")) {\n        // registration rejected by server: check vgroupMapping/version, do NOT blind-retry\n        throw new ConfigurationException(\"RM registration rejected: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Make client txServiceGroup and server service.vgroupMapping part of the same deploy config so they cannot drift.","Pin client and server to the same org.apache.seata minor version.","Log and alert on first registration failure — retries will not fix a config mismatch."],"tags":["client","rm","registration","transaction-group","version-mismatch"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}