alibaba/canal · error · NullPointerException

null zkClient

Error message

null zkClient

What it means

ZooKeeperLogPositionManager reads and writes binlog positions directly to ZooKeeper nodes. Its only dependency is a ZkClientx; a null client throws NullPointerException at construction because there is no way to reach the store.

Source

Thrown at parse/src/main/java/com/alibaba/otter/canal/parse/index/ZooKeeperLogPositionManager.java:20

import org.I0Itec.zkclient.exception.ZkNoNodeException;

import com.alibaba.otter.canal.common.utils.JsonUtils;
import com.alibaba.otter.canal.common.zookeeper.ZkClientx;
import com.alibaba.otter.canal.common.zookeeper.ZookeeperPathUtils;
import com.alibaba.otter.canal.parse.exception.CanalParseException;
import com.alibaba.otter.canal.protocol.position.LogPosition;

/**
 * Created by yinxiu on 17/3/17. Email: marklin.hz@gmail.com
 */
public class ZooKeeperLogPositionManager extends AbstractLogPositionManager {

    private final ZkClientx zkClientx;

    public ZooKeeperLogPositionManager(ZkClientx zkClient){
        if (zkClient == null) {
            throw new NullPointerException("null zkClient");
        }

        this.zkClientx = zkClient;
    }

    @Override
    public LogPosition getLatestIndexBy(String destination) {
        String path = ZookeeperPathUtils.getParsePath(destination);
        byte[] data = zkClientx.readData(path, true);
        if (data == null || data.length == 0) {
            return null;
        }

        return JsonUtils.unmarshalFromByte(data, LogPosition.class);
    }

    @Override
    public void persistLogPosition(String destination, LogPosition logPosition) throws CanalParseException {

View on GitHub (pinned to 87be50e876)

Solutions

  1. Configure canal.zkServers with a reachable ZooKeeper address.
  2. Build ZkClientx via ZkClientx.getZkClient(...) and confirm it is non-null before constructing the manager.
  3. For tests, stand up an embedded ZooKeeper TestingServer.

Example fix

// before
new ZooKeeperLogPositionManager(null);

// after
ZkClientx zk = ZkClientx.getZkClient(zkServers);
new ZooKeeperLogPositionManager(Objects.requireNonNull(zk, "zkClient"));
Defensive patterns

Strategy: validation

Validate before calling

ZkClientx zk = Objects.requireNonNull(zkClient, "zkClient");
new ZooKeeperLogPositionManager(zk);

Type guard

boolean hasZkClient(ZkClientx z) { return z != null; }

Prevention

When it happens

Trigger: Calling `new ZooKeeperLogPositionManager(zkClient)` with zkClient == null. This typically propagates upward (it also causes MixedLogPositionManager/PeriodMixed failures) when the zk client was never built.

Common situations: `canal.zkServers` unset; ZkClientx construction failed silently and returned null; a test environment without a ZooKeeper instance.

Related errors


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