alibaba/canal · error · ZkException

zookeeper_create_error, serveraddrs={}

Error message

zookeeper_create_error, serveraddrs={}

What it means

Thrown by ZooKeeperx.configMutliCluster when merging additional ZK cluster address lists via reflection fails. configMutliCluster only runs when the connect string contains ';' (multi-cluster fallback). It reflectively appends a second cluster's InetSocketAddress list into the first ZooKeeper's HostProvider; any reflection or address-parse failure closes the zk handle and throws ZkException carrying the first cluster string. This usually indicates an incompatible ZooKeeper client version (reflection field names changed) or a malformed second-cluster connect string.

Source

Thrown at common/src/main/java/com/alibaba/otter/canal/common/zookeeper/ZooKeeperx.java:117

                    String cluster = _serversList.get(i);
                    // 强制获取zk中的地址信息
                    ClientCnxn cnxn = (ClientCnxn) ReflectionUtils.getField(clientCnxnField, zk);
                    HostProvider hostProvider = (HostProvider) ReflectionUtils.getField(hostProviderField, cnxn);
                    List<InetSocketAddress> serverAddrs = (List<InetSocketAddress>) ReflectionUtils.getField(serverAddressesField,
                        hostProvider);
                    // 添加第二组集群列表
                    serverAddrs.addAll(new ConnectStringParser(cluster).getServerAddresses());
                }
            }
        } catch (Exception e) {
            try {
                if (zk != null) {
                    zk.close();
                }
            } catch (InterruptedException ie) {
                // ignore interrupt
            }
            throw new ZkException("zookeeper_create_error, serveraddrs=" + cluster1, e);
        }

    }
}

View on GitHub (pinned to 87be50e876)

Solutions

  1. Use a single ZK ensemble (no ';') if multi-cluster failover is not required — configMutliCluster returns early and the failure path is skipped.
  2. Ensure the zookeeper client jar version matches the one canal was built/tested against (check pom dependency versions) so reflective fields exist.
  3. Validate the second cluster connect string (host:port pairs, comma-separated) is syntactically correct.
  4. If you need multi-cluster failover, pin the exact supported zookeeper version or avoid this proprietary multi-cluster feature.

Example fix

# before
canal.zkServers = zk-hz-1:2181,zk-hz-2:2181;zk-us-1:2181,zk-us-2:notaport
# after
canal.zkServers = zk-hz-1:2181,zk-hz-2:2181,zk-hz-3:2181
Defensive patterns

Strategy: validation

Validate before calling

// Validate multi-cluster connect string shape before constructing ZooKeeperx
void validateMultiCluster(String zkServers) {
    if (zkServers == null || zkServers.trim().isEmpty()) {
        throw new IllegalArgumentException("canal.zkServers is empty");
    }
    for (String cluster : zkServers.split(";")) {
        for (String hp : cluster.split(",")) {
            String[] parts = hp.split(":");
            if (parts.length != 2 || !parts[1].matches("\\d+")) {
                throw new IllegalArgumentException("bad ZK host:port " + hp);
            }
        }
    }
}

Try / catch

try {
    new ZooKeeperx(zkServers).connect(watcher);
} catch (org.I0Itec.zkclient.exception.ZkException e) {
    if (e.getMessage().startsWith("zookeeper_create_error")) {
        // multi-cluster merge failed: fall back to a single ensemble
        new ZooKeeperx(firstClusterOnly(zkServers)).connect(watcher);
    } else throw e;
}

Prevention

When it happens

Trigger: canal.zkServers uses ';' to separate two clusters (e.g. 'a:2181;b:2181') and either (a) the bundled zookeeper.jar lacks the reflectively-accessed fields 'cnxn'/'hostProvider'/'serverAddresses' (version drift), or (b) the second cluster string is unparseable by ConnectStringParser.

Common situations: Upgrading zookeeper client jar changed ClientCnxn internals so ReflectionUtils.findField returns a field whose value shape differs; using a multi-region ZK failover config where the secondary cluster string is malformed; running a shaded/relocated zookeeper jar.

Related errors


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