alibaba/canal · error · ServerIdNotMatchException

unexpected rds serverId + serverId + in binlog file !

Error message

unexpected rds serverId  + serverId +  in binlog file !

What it means

Thrown as ServerIdNotMatchException by LocalBinLogConnection.checkServerId in RDS-OSS mode when a binlog event's serverId is neither the configured serverId nor already known in rdsOssMasterSlaveInfo. In RDS-OSS mode the first differing serverId seeds the master-slave set; subsequent unknown serverIds are rejected as foreign to protect against mixing unrelated instances' binlogs.

Solutions

  1. Confirm the OSS binlog files belong to the intended instance and its known replicas only.
  2. Set canal.instance.master.serverId / the LocalBinLogConnection serverId to match the binlog's primary server_id.
  3. If multi-source is intentional, ensure all expected replica serverIds are encountered in the correct seeding order (the first new id becomes the slave set).
  4. Re-verify isRdsOssMode configuration; if not actually RDS-OSS, disable it to use the plain serverId check instead.
Defensive patterns

Strategy: validation

Validate before calling

// before replay, confirm every serverId in the OSS bundle is expected
Set<Long> ids = listBinlogServerIds(directory);
if (!expectedMasterSlaveIds.containsAll(ids)) throw new IllegalStateException("unexpected serverIds: " + ids);

Try / catch

try { conn.dump(...); }
catch (ServerIdNotMatchException e) {
    // either widen the allowed set or fix the configured serverId
    log.warn("foreign serverId in rds-oss bundle: {}", e.getMessage());
}

Prevention

When it happens

Trigger: checkServerId(event): serverId != 0 and event.getServerId() != serverId, isRdsOssMode() true, firstUpdateRdsOssMasterSlave already false, and rdsOssMasterSlaveInfo.contains(event.getServerId()) is false. So a third+ distinct serverId appears in the streamed binlog.

Common situations: Replaying an OSS binlog bundle that unexpectedly contains events from an extra MySQL node (e.g. a new replica promoted, or binlogs from a different instance mixed in), or the configured serverId does not match the OSS binlog's actual server_id. Also if the first event seeded the wrong id due to ordering.

Related errors


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

Appendix: source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/inbound/mysql/LocalBinLogConnection.java:170

    /**
     * 1. 非 rdsOos 模式下需要要校验 serverId 是否一致 防止解析其他实例的 binlog <br/>
     * 2. rdsOos 高可用模式下解析 binlog
     * 会有两个 serverId,分别对应着主从节点 binlog解析出来的 serverId 主从的关系可能会变, 但是 serverId一直都会是这两个
     * serverId
     *
     * @param event
     */
    private void checkServerId(LogEvent event) {
        if (serverId != 0 && event.getServerId() != serverId) {
            if (isRdsOssMode()) {
                // 第一次添加主从信息
                if (firstUpdateRdsOssMasterSlave) {
                    firstUpdateRdsOssMasterSlave = false;
                    rdsOssMasterSlaveInfo.add(event.getServerId());
                } else if (!rdsOssMasterSlaveInfo.contains(event.getServerId())) {
                    // 主从节点信息之外的节点信息
                    throw new ServerIdNotMatchException("unexpected rds serverId " + serverId + " in binlog file !");
                }
            } else {
                throw new ServerIdNotMatchException("unexpected serverId " + serverId + " in binlog file !");
            }
        }
    }

    public void dump(long timestampMills, SinkFunction func) throws IOException {
        List<File> currentBinlogs = binlogs.currentBinlogs();
        File current = currentBinlogs.get(currentBinlogs.size() - 1);
        long timestampSeconds = timestampMills / 1000;

        String binlogFilename = null;
        long binlogFileOffset = 0;

        FileLogFetcher fetcher = new FileLogFetcher(bufferSize);
        LogDecoder decoder = new LogDecoder();
        decoder.handle(LogEvent.FORMAT_DESCRIPTION_EVENT);

View on GitHub (pinned to 87be50e876)