apache/incubator-seata · error · FrameworkException
0109
0109
Error message
frameworkException
What it means
Thrown by the Seata remoting client when sendAsyncRequest(Channel, Object) is invoked with a null channel. Instead of silently dropping the message, the client wraps a dummy Throwable in a FrameworkException with code ChannelIsNotWritable (0109). It almost always means the RM/TM had no live connection to the TC when an async (one-way or merged) request was attempted.
Source
Thrown at core/src/main/java/org/apache/seata/core/rpc/netty/AbstractNettyRemotingClient.java:233
return super.sendSync(channel, rpcMessage, timeoutMillis);
}
}
@Override
public Object sendSyncRequest(Channel channel, Object msg) throws TimeoutException {
if (channel == null) {
LOGGER.warn("sendSyncRequest nothing, caused by null channel.");
return null;
}
RpcMessage rpcMessage = buildRequestMessage(msg, ProtocolConstants.MSGTYPE_RESQUEST_SYNC);
return super.sendSync(channel, rpcMessage, this.getRpcRequestTimeout());
}
@Override
public void sendAsyncRequest(Channel channel, Object msg) {
if (channel == null) {
LOGGER.warn("sendAsyncRequest nothing, caused by null channel.");
throw new FrameworkException(
new Throwable("throw"), "frameworkException", FrameworkErrorCode.ChannelIsNotWritable);
}
RpcMessage rpcMessage = buildRequestMessage(
msg,
msg instanceof HeartbeatMessage
? ProtocolConstants.MSGTYPE_HEARTBEAT_REQUEST
: ProtocolConstants.MSGTYPE_RESQUEST_ONEWAY);
Object body = rpcMessage.getBody();
if (body instanceof MergeMessage) {
Integer parentId = rpcMessage.getId();
mergeMsgMap.put(parentId, (MergeMessage) rpcMessage.getBody());
if (body instanceof MergedWarpMessage) {
for (Integer msgId : ((MergedWarpMessage) rpcMessage.getBody()).msgIds) {
childToParentMap.put(msgId, parentId);
}
}
}
super.sendAsync(channel, rpcMessage);View on GitHub (pinned to e01f97c6db)
Solutions
- Check that the client is registered and the channel is active before sending: channel != null && channel.isActive()
- Verify the seata server is reachable and the client has completed TM/RM registration (look for 'register success' logs)
- If sending to a specific server, re-acquire the channel via the client channel manager instead of caching a Channel reference
- Increase reconnect logic coverage: ensure doReconnect runs for your transaction service group (registry config serviceGroup -> cluster mapping)
Example fix
// before
client.sendAsyncRequest(channel, branchRegisterRequest);
// after
if (channel != null && channel.isActive()) {
client.sendAsyncRequest(channel, branchRegisterRequest);
} else {
LOGGER.warn("channel inactive, skipping async request; waiting for reconnect");
} Defensive patterns
Strategy: validation
Validate before calling
if (channel == null || !channel.isActive()) {
LOGGER.warn("skip async request: channel null or inactive");
return; // or trigger reconnect
}
client.sendAsyncRequest(channel, msg); Try / catch
catch (FrameworkException e) {
if (e.getErrCode() == FrameworkErrorCode.ChannelIsNotWritable) {
// schedule reconnect and retry once the channel is back
} else { throw e; }
} Prevention
- Never cache Channel references across requests; resolve per send
- Watch client logs for 'register success' before issuing the first requests
- Monitor channel active state in a health check when embedding seata client
When it happens
Trigger: Calling AbstractNettyRemotingClient.sendAsyncRequest(channel, msg) where the channel argument is null; typical upstream paths are heartbeats or merged message sends after the server channel was closed/invalidated but the caller kept the stale reference.
Common situations: Seata server restart or network flap invalidating the client channel; the client has not yet finished reconnecting when a branch register/global report fires; proxies capturing a channel before registration completes.
Related errors
- connect cancelled, can not connect to services-server.
- 0109
- client is not connected
- connect failed, can not connect to services-server.
- can not connect to [{invalidAddress}]
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/d2e48541d5f132d4.
Report an issue: GitHub.