{"record":{"id":"831488cf693fd5ee","repo":"alibaba/canal","slug":"disconnect-address-s-has-an-error-retrying","errorCode":null,"errorMessage":"disconnect address %s has an error, retrying. ","messagePattern":"disconnect address (.+?) has an error, retrying\\. ","errorType":"exception","errorClass":"CanalParseException","httpStatus":null,"severity":"warning","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/AbstractEventParser.java","lineNumber":311,"sourceCode":"                            logger.error(String.format(\"dump address %s has an error, retrying. caused by \",\r\n                                runningInfo.getAddress().toString()), e);\r\n                            sendAlarm(destination, ExceptionUtils.getFullStackTrace(e));\r\n                        }\r\n                        if (parserExceptionHandler != null) {\r\n                            parserExceptionHandler.handle(e);\r\n                        }\r\n                    } finally {\r\n                        // 重新置为中断状态\r\n                        Thread.interrupted();\r\n                        // 关闭一下链接\r\n                        afterDump(erosaConnection);\r\n                        try {\r\n                            if (erosaConnection != null) {\r\n                                erosaConnection.disconnect();\r\n                            }\r\n                        } catch (IOException e1) {\r\n                            if (!running) {\r\n                                throw new CanalParseException(String.format(\"disconnect address %s has an error, retrying. \",\r\n                                    runningInfo.getAddress().toString()),\r\n                                    e1);\r\n                            } else {\r\n                                logger.error(\"disconnect address {} has an error, retrying., caused by \",\r\n                                    runningInfo.getAddress().toString(),\r\n                                    e1);\r\n                            }\r\n                        }\r\n                    }\r\n                    // 出异常了，退出sink消费，释放一下状态\r\n                    eventSink.interrupt();\r\n                    transactionBuffer.reset();// 重置一下缓冲队列，重新记录数据\r\n                    binlogParser.reset();// 重新置位\r\n                    if (multiStageCoprocessor != null && multiStageCoprocessor.isStart()) {\r\n                        // 处理 RejectedExecutionException\r\n                        try {\r\n                            multiStageCoprocessor.stop();\r\n                        } catch (Throwable t) {\r","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/AbstractEventParser.java#L293-L329","documentation":"Thrown as CanalParseException (only when !running) from the finally block when erosaConnection.disconnect() raises an IOException during a dump-cycle teardown. Like 369, while running this is merely logged; it is rethrown only because the parser is no longer running, signalling that the disconnect cleanup itself failed during shutdown.","triggerScenarios":"In the dump loop's finally block, afterDump then erosaConnection.disconnect() throws IOException; if running==false the CanalParseException is thrown with the address; otherwise it is logged and the cycle continues (sink interrupted, buffer reset, retry).","commonSituations":"Stopping the parser while the socket is already broken (MySQL restarted, network dropped, TCP RST), so closing the connection raises IOException. Generally benign during shutdown but can mask the original dump error.","solutions":["During shutdown, treat as non-fatal cleanup noise; check the preceding dump error (369) for the real cause.","Ensure network stability to the MySQL source; persistent RST during disconnect hints at firewall/idle-timeout killing the socket.","Upgrade driver/connector if disconnect throws due to a known bug in the binlog client.","Do not conflate this with data loss; it only affects teardown of an already-failed connection."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// the source already logs while running; only rethrows when !running.\n// at the caller, swallow disconnect IOException during shutdown:\ntry { erosaConnection.disconnect(); } catch (IOException ignore) { /* shutting down */ }","preventionTips":["Treat disconnect errors during shutdown as cleanup noise.","Investigate the preceding dump error for the real cause.","Keep the MySQL socket healthy to reduce teardown failures."],"tags":["parse","connection-cleanup","shutdown","mysql-connection"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}