alibaba/canal · error · IOException
socket has Interrupted !
Error message
socket has Interrupted !
What it means
Thrown by NettySocketChannel.read(int,int) when cache has fewer bytes than readSize and channel is null, i.e. the netty channel has been closed (close() nulls channel) while the reader is still waiting for data. Distinct from the timeout branch: here the channel disappeared, so waiting is pointless. The same message is reused for the InterruptedException-from-wait path.
Source
Thrown at driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/NettySocketChannel.java:175
throw new IOException("write failed ! please checking !");
}
}
public byte[] read(int readSize) throws IOException {
return read(readSize, 0);
}
public byte[] read(int readSize, int timeout) throws IOException {
int accumulatedWaitTime = 0;
// 若读取内容较长,则自动扩充超时时间,以初始缓存大小为基准计算倍数
if (timeout > 0 && readSize > DEFAULT_INIT_BUFFER_SIZE) {
timeout *= (readSize / DEFAULT_INIT_BUFFER_SIZE + 1);
}
do {
if (readSize > cache.readableBytes()) {
if (null == channel) {
throw new IOException("socket has Interrupted !");
}
if (timeout > 0) {
accumulatedWaitTime += WAIT_PERIOD;
if (accumulatedWaitTime > timeout) {
StringBuilder sb = new StringBuilder("socket read timeout occured !");
sb.append(" readSize = ").append(readSize);
sb.append(", readableBytes = ").append(cache.readableBytes());
sb.append(", timeout = ").append(timeout);
throw new IOException(sb.toString());
}
}
synchronized (this) {
try {
wait(WAIT_PERIOD);
} catch (InterruptedException e) {
throw new IOException("socket has Interrupted !");
View on GitHub (pinned to 87be50e876)
Solutions
- Ensure the reader thread is stopped/interrupted cleanly before close() so it exits the wait loop.
- Treat this IOException as a shutdown signal and break the read loop rather than propagating as a hard failure.
- Coordinate close() and read() via a shared state flag (e.g. volatile boolean running).
- Do not reuse the NettySocketChannel across reconnects.
Example fix
// before
byte[] b = channel.read(len, timeoutMs); // throws 'socket has Interrupted !'
// after
try {
byte[] b = channel.read(len, timeoutMs);
} catch (IOException e) {
if (e.getMessage().contains("Interrupted") || !running) {
// graceful shutdown of the reader
return;
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Reader loop: check a running flag and channel state before waiting
if (!running || channel == null || !channel.isConnected()) { break; } Type guard
public static boolean canReadNetty(NettySocketChannel nsc) {
return nsc != null && nsc.getChannel() != null;
} Try / catch
try {
byte[] b = nettyChannel.read(len, timeoutMs);
} catch (java.io.IOException e) {
if (e.getMessage() != null && e.getMessage().contains("Interrupted")) {
// graceful reader shutdown; exit loop
return;
}
throw e;
} Prevention
- Signal a running flag false and stop reader threads before close().
- Treat 'socket has Interrupted !' as a shutdown signal, not a hard failure.
- Do not reuse NettySocketChannel instances across reconnects.
When it happens
Trigger: Reader thread in the wait-loop when close() sets channel=null; or the wait() is interrupted (InterruptedException caught) and re-thrown as this IOException. Happens during shutdown, reconnect, or when the reader thread is interrupted while blocked.
Common situations: Binlog parser thread blocked in read while an admin/error thread closes the channel; JVM shutdown interrupting reader threads; reconnect logic that closes the old channel before the reader exits its wait loop.
Related errors
- socket is closed !
- write failed ! please checking !
- Socket already closed.
- end of stream when reading header
- Disconnect pulsar consumer error
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/61d5037578d2e9db.
Report an issue: GitHub.