alibaba/canal · error · CanalException

master/slave Sourcing type is unmatch. %s vs %s

Error message

master/slave Sourcing type is unmatch. %s vs %s

What it means

Thrown in initEventParser() (CanalInstanceWithManager.java:232-235) while iterating group database addresses: at each index i across the configured groups, the SourcingType must match the previous group's SourcingType at the same index. If two groups disagree (e.g. group[0][i]=MYSQL and group[1][i]=LOCALBINLOG), canal raises CanalException 'master/slave Sourcing type is unmatch. <lastType> vs <currentType>'. Canal builds one parser per index position across all groups and requires homogeneous source types per position.

Source

Thrown at instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/CanalInstanceWithManager.java:233

        // ((AbstractCanalEventSink) eventSink).setFilter(aviaterFilter);
        // }
        logger.info("init eventSink end! \n\t load CanalEventSink:{}", eventSink.getClass().getName());
    }

    protected void initEventParser() {
        logger.info("init eventParser begin...");
        SourcingType type = parameters.getSourcingType();

        List<List<DataSourcing>> groupDbAddresses = parameters.getGroupDbAddresses();
        if (!CollectionUtils.isEmpty(groupDbAddresses)) {
            int size = groupDbAddresses.get(0).size();// 取第一个分组的数量,主备分组的数量必须一致
            List<CanalEventParser> eventParsers = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                List<InetSocketAddress> dbAddress = new ArrayList<>();
                SourcingType lastType = null;
                for (List<DataSourcing> groupDbAddress : groupDbAddresses) {
                    if (lastType != null && !lastType.equals(groupDbAddress.get(i).getType())) {
                        throw new CanalException(String.format("master/slave Sourcing type is unmatch. %s vs %s",
                            lastType,
                            groupDbAddress.get(i).getType()));
                    }

                    lastType = groupDbAddress.get(i).getType();
                    dbAddress.add(groupDbAddress.get(i).getDbAddress());
                }

                // 初始化其中的一个分组parser
                eventParsers.add(doInitEventParser(lastType, dbAddress));
            }

            if (eventParsers.size() > 1) { // 如果存在分组,构造分组的parser
                GroupEventParser groupEventParser = new GroupEventParser();
                groupEventParser.setEventParsers(eventParsers);
                this.eventParser = groupEventParser;
            } else {
                this.eventParser = eventParsers.get(0);

View on GitHub (pinned to 87be50e876)

Solutions

  1. Align SourcingTypes per index across all groups — every group's i-th entry must share the same SourcingType (all MYSQL, or all LOCALBINLOG). The exception message names the two conflicting types to pinpoint the index.
  2. Re-check the canal.instance.group.<groupIndex>.db.* and corresponding type settings; ensure the number of entries per group is identical (the code assumes equal size, taking groupDbAddresses.get(0).size()).
  3. If you need heterogeneous sources, run separate canal instances rather than grouping them.
  4. Strip stray/empty group entries that shift indices.

Example fix

# before — mismatched types at index 0
canal.instance.group1.db.tcpHost = mysql-a:3306      # MYSQL
canal.instance.group2.localBinlog.dir = /data/binlog  # LOCALBINLOG at same index

# after — homogeneous per index
canal.instance.group1.db.tcpHost = mysql-a:3306
canal.instance.group2.db.tcpHost = mysql-b:3306
Defensive patterns

Strategy: validation

Validate before calling

// Validate that every group has the same SourcingType at each index before starting
List<List<DataSourcing>> groups = parameters.getGroupDbAddresses();
if (!CollectionUtils.isEmpty(groups)) {
    int size = groups.get(0).size();
    for (int i = 0; i < size; i++) {
        SourcingType first = groups.get(0).get(i).getType();
        for (int g = 1; g < groups.size(); g++) {
            if (!first.equals(groups.get(g).get(i).getType())) {
                throw new IllegalArgumentException(String.format(
                    "SourcingType mismatch at index %d: %s vs %s", i, first, groups.get(g).get(i).getType()));
            }
        }
    }
}

Prevention

When it happens

Trigger: Configuring canal.instance.group.<n>.db addresses (groupDbAddresses) where the master/standby lists mix SourcingTypes at the same position — e.g. group groupA lists a MYSQL address at position 0 and group groupB lists a LOCALBINLOG or ORACLE address at position 0. The comparison runs during instance startup in initEventParser.

Common situations: Multi-group HA setup where one group is MySQL and another was intended as a local-binlog fallback but placed at the same index; copy-paste of group config with a different source type; mixing a TDDL/Oracle source into a MySQL group; miscounted group entries causing index misalignment.

Related errors


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