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.

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)

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.