apache/incubator-seata · error · FrameworkException
can not register RM,err:%s
Error message
can not register RM,err:%s
What it means
FrameworkException from NettyClientChannelManager.acquireChannel: borrowing a channel from the Netty channel pool failed, which in Seata means the connect plus TM/RM register handshake inside NettyPoolableFactory.makeObject threw. The message appends the underlying cause's message; the code above also logs it with the RegisterRM error code.
Source
Thrown at core/src/main/java/org/apache/seata/core/rpc/netty/NettyClientChannelManager.java:353
if (removed && LOGGER.isInfoEnabled()) {
LOGGER.info("Cleaned up channel metadata for disconnected address: {}", serverAddress);
}
}
private Channel doConnect(String serverAddress) {
Channel channelToServer = channels.get(serverAddress);
if (channelToServer != null && channelToServer.isActive()) {
return channelToServer;
}
Channel channelFromPool;
try {
NettyPoolKey currentPoolKey = poolKeyFunction.apply(serverAddress);
poolKeyMap.put(serverAddress, currentPoolKey);
channelFromPool = nettyClientKeyPool.borrowObject(currentPoolKey);
channels.put(serverAddress, channelFromPool);
} catch (Exception exx) {
LOGGER.error("{} register RM failed.", FrameworkErrorCode.RegisterRM.getErrCode(), exx);
throw new FrameworkException("can not register RM,err:" + exx.getMessage());
}
return channelFromPool;
}
private List<String> getAvailServerList(String transactionServiceGroup) throws Exception {
List<InetSocketAddress> availInetSocketAddressList =
RegistryFactory.getInstance().lookup(transactionServiceGroup);
if (CollectionUtils.isEmpty(availInetSocketAddressList)) {
return Collections.emptyList();
}
return availInetSocketAddressList.stream().map(NetUtil::toStringAddress).collect(Collectors.toList());
}
private Channel getExistAliveChannel(Channel rmChannel, String serverAddress) {
if (rmChannel.isActive()) {
return rmChannel;
} else {View on GitHub (pinned to e01f97c6db)
Solutions
- Check the preceding 'register RM failed' log entry and its cause — it names the real failure
- Confirm seata-server is running and accepting registrations; test with a fresh client start
- Align auth config: if the server requires username/password, set them on the client
- Align client/server versions and retry the business operation after the client reconnects
Example fix
# application.yml — server has auth enabled
seata:
client:
tm:
username: seata
password: seata
rm:
username: seata
password: seata Defensive patterns
Strategy: retry
Validate before calling
// before RM operations, confirm a live channel exists Channel ch = channelManager.acquireChannel(serverAddress); // throws with cause if register fails
Try / catch
catch (FrameworkException e) {
if (e.getMessage().startsWith("can not register RM")) {
// inspect cause: auth/timeout/unreachable; fix and let background reconnect re-register
}
} Prevention
- Keep client credentials in sync with server auth config
- Retain server availability through RM-heavy traffic windows
- Retry business operations once after re-registration succeeds
When it happens
Trigger: Calling an RM API (branch register, lock queries, SQL undo operations) that needs a server channel while pool.borrowObject fails: server unreachable, register request rejected/timed out, or the pool's register validation (isRegisterSuccess) failed and onRegisterMsgFail threw.
Common situations: seata-server restarted and the client's cached pool keys are stale; registration rejected due to authentication (server enabled auth, client missing username/password); version-incompatible register responses; brief outage during the first business SQL after startup.
Related errors
- register msg is null, role:%s
- register RM failed. client version: %s,server version: %s, e
- register %s error, errMsg:%s
- register TM failed. client version: %s,server version: %s, e
- applicationId: %s, txServiceGroup: %s
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/667887490d9d7bba.
Report an issue: GitHub.