{"record":{"id":"8829c1423c861d70","repo":"alibaba/canal","slug":"write-failed-please-checking","errorCode":null,"errorMessage":"write failed ! please checking !","messagePattern":"write failed ! please checking !","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/NettySocketChannel.java","lineNumber":157,"sourceCode":"                        cache.writeBytes(buf, length);\r\n                        break;\r\n                    } else {\r\n                        cache.writeBytes(buf, length - deltaSize);\r\n                    }\r\n                }\r\n                // dest buffer is full.\r\n                lock.wait(WAIT_PERIOD);\r\n                // 回收已读空间，重置读写指针\r\n                cache.discardReadBytes();\r\n            }\r\n        }\r\n    }\r\n\r\n    public void write(byte[]... buf) throws IOException {\r\n        if (channel != null && channel.isWritable()) {\r\n            channel.writeAndFlush(Unpooled.copiedBuffer(buf));\r\n        } else {\r\n            throw new IOException(\"write failed ! please checking !\");\r\n        }\r\n    }\r\n\r\n    public byte[] read(int readSize) throws IOException {\r\n        return read(readSize, 0);\r\n    }\r\n\r\n    public byte[] read(int readSize, int timeout) throws IOException {\r\n        int accumulatedWaitTime = 0;\r\n\r\n        // 若读取内容较长，则自动扩充超时时间，以初始缓存大小为基准计算倍数\r\n        if (timeout > 0 && readSize > DEFAULT_INIT_BUFFER_SIZE) {\r\n            timeout *= (readSize / DEFAULT_INIT_BUFFER_SIZE + 1);\r\n        }\r\n        do {\r\n            if (readSize > cache.readableBytes()) {\r\n                if (null == channel) {\r\n                    throw new IOException(\"socket has Interrupted !\");\r","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/NettySocketChannel.java#L139-L175","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check isConnected()/channel!=null before writing and reopen if closed.","For back-pressure, throttle the producer or raise the channel's write-buffer watermark (Channel.config().setWriteBufferHighWaterMark).","Flush more frequently or ensure the outbound handler drains bytes.","Drop or reject writes gracefully instead of throwing once the buffer is full."],"exampleFix":"// before\nchannel.write(payload); // throws when not writable / null\n\n// after\nif (channel == null || !channel.isConnected()) {\n    channel = reopen();\n}\nif (!channel.isWritable()) {\n    // apply backpressure: wait or drop\n    throw new IOException(\"channel not writable, apply backpressure\");\n}\nchannel.write(payload);","handlingStrategy":"validation","validationCode":"if (channel == null || !channel.isConnected()) { channel = reopen(); }\n// for backpressure: check writability\nChannel ch = nettyChannel.getChannel();\nif (ch == null || !ch.isWritable()) { /* throttle or wait */ }","typeGuard":"public static boolean isNettyWritable(NettySocketChannel nsc) {\n    io.netty.channel.Channel ch = nsc.getChannel();\n    return ch != null && ch.isActive() && ch.isWritable();\n}","tryCatchPattern":"try {\n    nettyChannel.write(payload);\n} catch (java.io.IOException e) {\n    if (\"write failed ! please checking !\".equals(e.getMessage())) {\n        // reopen if closed, or apply backpressure if just not writable\n    }\n    throw e;\n}","preventionTips":["Check isConnected()/isWritable() before writing.","Raise the netty write-buffer high-water mark if back-pressure is frequent.","Recreate the channel after close rather than reusing it."],"tags":["network","netty","io","lifecycle","backpressure"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}