{"record":{"id":"58e64438523cb88d","repo":"alibaba/canal","slug":"unexpected-serverid-serverid-in-binlog-file","errorCode":null,"errorMessage":"unexpected serverId  + serverId +  in binlog file !","messagePattern":"unexpected serverId  \\+ serverId \\+  in binlog file !","errorType":"exception","errorClass":"ServerIdNotMatchException","httpStatus":null,"severity":"error","filePath":"parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/LocalBinLogConnection.java","lineNumber":173,"sourceCode":"     * 2. rdsOos 高可用模式下解析 binlog\r\n     * 会有两个 serverId,分别对应着主从节点 binlog解析出来的 serverId 主从的关系可能会变, 但是 serverId一直都会是这两个\r\n     * serverId\r\n     *\r\n     * @param event\r\n     */\r\n    private void checkServerId(LogEvent event) {\r\n        if (serverId != 0 && event.getServerId() != serverId) {\r\n            if (isRdsOssMode()) {\r\n                // 第一次添加主从信息\r\n                if (firstUpdateRdsOssMasterSlave) {\r\n                    firstUpdateRdsOssMasterSlave = false;\r\n                    rdsOssMasterSlaveInfo.add(event.getServerId());\r\n                } else if (!rdsOssMasterSlaveInfo.contains(event.getServerId())) {\r\n                    // 主从节点信息之外的节点信息\r\n                    throw new ServerIdNotMatchException(\"unexpected rds serverId \" + serverId + \" in binlog file !\");\r\n                }\r\n            } else {\r\n                throw new ServerIdNotMatchException(\"unexpected serverId \" + serverId + \" in binlog file !\");\r\n            }\r\n        }\r\n    }\r\n\r\n    public void dump(long timestampMills, SinkFunction func) throws IOException {\r\n        List<File> currentBinlogs = binlogs.currentBinlogs();\r\n        File current = currentBinlogs.get(currentBinlogs.size() - 1);\r\n        long timestampSeconds = timestampMills / 1000;\r\n\r\n        String binlogFilename = null;\r\n        long binlogFileOffset = 0;\r\n\r\n        FileLogFetcher fetcher = new FileLogFetcher(bufferSize);\r\n        LogDecoder decoder = new LogDecoder();\r\n        decoder.handle(LogEvent.FORMAT_DESCRIPTION_EVENT);\r\n        decoder.handle(LogEvent.QUERY_EVENT);\r\n        decoder.handle(LogEvent.XID_EVENT);\r\n        LogContext context = new LogContext();\r","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/LocalBinLogConnection.java#L155-L191","documentation":"Thrown as ServerIdNotMatchException by LocalBinLogConnection.checkServerId in the NON-RDS-OSS branch when a binlog event's serverId differs from the configured serverId (serverId != 0). This guards local binlog replay so only events from the intended MySQL server_id are processed, filtering out any foreign events.","triggerScenarios":"checkServerId(event): serverId != 0, event.getServerId() != serverId, and isRdsOssMode() is false, so the else-branch throws. Triggered during local binlog dump/fetch when an event carries a server_id different from the configured one.","commonSituations":"LocalBinLogConnection.serverId is misconfigured (does not match the binlog's server_id), the binlog directory contains files from a different MySQL instance, or a HA failover changed the master server_id and the replay is now seeing the new id while serverId is pinned to the old one.","solutions":["Set LocalBinLogConnection.serverId to the actual server_id of the binlog files being replayed (or 0 to disable the check).","Ensure the binlog directory only contains files from the intended instance.","After a master failover, update serverId to the new master's server_id or disable the check (serverId=0) if mixing is acceptable.","Verify you are not accidentally pointing at a standby's binlogs when serverId is set for the primary."],"exampleFix":"// before\nlocalBinLogConnection.setServerId(1); // wrong id\n\n// after\nlocalBinLogConnection.setServerId(3306actualServerId);\n// or disable the filter\nlocalBinLogConnection.setServerId(0);","handlingStrategy":"validation","validationCode":"long actualServerId = readFirstEventServerId(new File(directory, firstBinlog));\nif (conn.getServerId() != 0 && conn.getServerId() != actualServerId) {\n    throw new IllegalStateException(\"configured serverId=\" + conn.getServerId() + \" != binlog serverId=\" + actualServerId);\n}","typeGuard":null,"tryCatchPattern":"try { conn.dump(...); }\ncatch (ServerIdNotMatchException e) {\n    conn.setServerId(0); // disable filter if mixing is acceptable\n    conn.dump(...);\n}","preventionTips":["Set serverId to the binlog's actual server_id, or 0 to disable.","Keep one instance's binlogs per replay directory.","Update serverId after a master failover."],"tags":["parse","binlog","serverid","local-binlog"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}