apache/incubator-seata · error · FrameworkException

register TM failed. client version: %s,server version: %s, e

Error message

register TM failed. client version: %s,server version: %s, errorMsg: %s, channel: %s

What it means

Thrown from TmNettyRemotingClient.onRegisterMsgFail: the Seata Server returned a failure RegisterTMResponse for the transaction-manager registration request. The message captures client/server versions, the server's errorMsg, and the channel, wrapped in FrameworkException. The server explicitly refused the TM registration rather than the channel failing.

Source

Thrown at core/src/main/java/org/apache/seata/core/rpc/netty/TmNettyRemotingClient.java:261

        if (LOGGER.isInfoEnabled()) {
            LOGGER.info(
                    "register TM success. client version:{}, server version:{},channel:{}",
                    registerTMRequest.getVersion(),
                    registerTMResponse.getVersion(),
                    channel);
        }
        getClientChannelManager().registerChannel(serverAddress, channel, registerTMRequest.getVersion());
    }

    @Override
    public void onRegisterMsgFail(
            String serverAddress, Channel channel, Object response, AbstractMessage requestMessage) {
        RegisterTMRequest registerTMRequest = (RegisterTMRequest) requestMessage;
        RegisterTMResponse registerTMResponse = (RegisterTMResponse) response;
        String errMsg = String.format(
                "register TM failed. client version: %s,server version: %s, errorMsg: %s, " + "channel: %s",
                registerTMRequest.getVersion(), registerTMResponse.getVersion(), registerTMResponse.getMsg(), channel);
        throw new FrameworkException(errMsg);
    }

    @Override
    public void destroy() {
        super.destroy();
        initialized.getAndSet(false);
        instance = null;
    }

    @Override
    protected Function<String, NettyPoolKey> getPoolKeyFunction() {
        return severAddress -> {
            RegisterTMRequest message = new RegisterTMRequest(applicationId, transactionServiceGroup, getExtraData());
            return new NettyPoolKey(NettyPoolKey.TransactionRole.TMROLE, severAddress, message);
        };
    }

    private void registerProcessor() {

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Compare the txServiceGroup string on the client against the server's seata.service.vgroupMapping keys (exact match, no typo, same case).
  2. Add/fix the mapping on the server (service.vgroupMapping.my_tx_group=default) and ensure the 'default' cluster is in the registry.
  3. Align client and server Seata versions if the errorMsg hints at version rejection.
  4. Confirm registry namespace/cluster/group on the client matches the server's registration so the TM reaches a server that owns the group.

Example fix

# before
# client: TMClient.init("app", "order_tx_group")
# server application.yml:
seata:
  service:
    vgroupMapping:
      order-group: "default"   # name mismatch -> register TM failed

# after
seata:
  service:
    vgroupMapping:
      order_tx_group: "default"
Defensive patterns

Strategy: validation

Validate before calling

// fail fast before TMClient.init if the transaction group resolves to no server
String group = "my_tx_group";
List<String> servers = io.seata.discovery.registry.RegistryFactory.getInstance().lookup(group);
if (servers == null || servers.isEmpty()) {
    throw new IllegalStateException("txServiceGroup '" + group + "' unknown - add it to server service.vgroupMapping");
}
TMClient.init(applicationId, group);

Try / catch

try {
    TMClient.init(applicationId, txServiceGroup);
} catch (io.seata.common.exception.FrameworkException e) {
    if (e.getMessage() != null && e.getMessage().contains("register TM failed")) {
        // server rejected the TM: surface as config error, include server errorMsg from the message
        throw new IllegalStateException("TM registration rejected: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: TMClient.init(applicationId, transactionServiceGroup) connects and sends RegisterTMRequest; the server responds with a non-success RegisterTMResponse — typically because the transaction service group is unknown to that server or a version/compatibility check failed.

Common situations: Client's txServiceGroup is not configured in server's service.vgroupMapping; client pointed at wrong registry namespace/cluster and reached a server that does not host the group; io.seata (1.x) client talking to an org.apache.seata (2.x) server; typo in the group name on either side.

Related errors


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