alibaba/canal · error · IOException

write failed ! please checking !

Error message

write failed ! please checking !

What it means

Thrown by NettySocketChannel.write when the netty Channel is null or not writable (channel.isWritable() false). A null channel means close() already ran (it sets channel=null); a non-writable channel means the outbound buffer is full / write buffer watermark exceeded. Either way the write is rejected outright.

Source

Thrown at driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/NettySocketChannel.java:157

                        cache.writeBytes(buf, length);
                        break;
                    } else {
                        cache.writeBytes(buf, length - deltaSize);
                    }
                }
                // dest buffer is full.
                lock.wait(WAIT_PERIOD);
                // 回收已读空间,重置读写指针
                cache.discardReadBytes();
            }
        }
    }

    public void write(byte[]... buf) throws IOException {
        if (channel != null && channel.isWritable()) {
            channel.writeAndFlush(Unpooled.copiedBuffer(buf));
        } else {
            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 !");

View on GitHub (pinned to 87be50e876)

Solutions

  1. Check isConnected()/channel!=null before writing and reopen if closed.
  2. For back-pressure, throttle the producer or raise the channel's write-buffer watermark (Channel.config().setWriteBufferHighWaterMark).
  3. Flush more frequently or ensure the outbound handler drains bytes.
  4. Drop or reject writes gracefully instead of throwing once the buffer is full.

Example fix

// before
channel.write(payload); // throws when not writable / null

// after
if (channel == null || !channel.isConnected()) {
    channel = reopen();
}
if (!channel.isWritable()) {
    // apply backpressure: wait or drop
    throw new IOException("channel not writable, apply backpressure");
}
channel.write(payload);
Defensive patterns

Strategy: validation

Validate before calling

if (channel == null || !channel.isConnected()) { channel = reopen(); }
// for backpressure: check writability
Channel ch = nettyChannel.getChannel();
if (ch == null || !ch.isWritable()) { /* throttle or wait */ }

Type guard

public static boolean isNettyWritable(NettySocketChannel nsc) {
    io.netty.channel.Channel ch = nsc.getChannel();
    return ch != null && ch.isActive() && ch.isWritable();
}

Try / catch

try {
    nettyChannel.write(payload);
} catch (java.io.IOException e) {
    if ("write failed ! please checking !".equals(e.getMessage())) {
        // reopen if closed, or apply backpressure if just not writable
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling write(...) on a closed channel (channel==null), or while the netty channel's write buffer is saturated so isWritable() returns false. The latter happens when the socket back-pressure rises faster than the peer drains.

Common situations: Writing after close (use-after-close); slow MySQL/server or congested network causing the netty outbound buffer to fill; high-throughput binlog producer outrunning the wire; the auto-read/write watermark is too low.

Related errors


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/8829c1423c861d70. Report an issue: GitHub.