alibaba/druid · error · DruidRuntimeException

ZK Client is NULL, Please set the zkConnectString.

Error message

ZK Client is NULL, Please set the zkConnectString.

What it means

ZookeeperNodeListener.checkParameters() throws this when neither a pre-built Curator client nor a zkConnectString was provided. The listener needs a live ZooKeeper connection to watch child nodes for HA data-source membership; with both null/empty it cannot create the PathChildrenCache. The method runs during start/refresh, so this surfaces at listener activation.

Source

Thrown at core/src/main/java/com/alibaba/druid/pool/ha/node/ZookeeperNodeListener.java:179

     */
    @Override
    public List<NodeEvent> refresh() {
        lock.lock();
        try {
            Properties properties = getPropertiesFromCache();
            List<NodeEvent> events = NodeEvent.getEventsByDiffProperties(getProperties(), properties);
            if (events != null && !events.isEmpty()) {
                setProperties(properties);
            }
            return events;
        } finally {
            lock.unlock();
        }
    }

    private void checkParameters() {
        if (client == null && StringUtils.isEmpty(zkConnectString)) {
            throw new DruidRuntimeException("ZK Client is NULL, Please set the zkConnectString.");
        }
        if (StringUtils.isEmpty(path)) {
            throw new DruidRuntimeException("Please set the ZooKeeper node path.");
        }
        if (StringUtils.isEmpty(urlTemplate)) {
            throw new DruidRuntimeException("Please set the urlTemplate.");
        }
    }

    private void updateSingleNode(PathChildrenCacheEvent event, NodeEventTypeEnum type) {
        ChildData data = event.getData();
        String nodeName = getNodeName(data);
        List<String> names = new ArrayList<String>();
        names.add(getPrefix() + "." + nodeName);
        Properties properties = getPropertiesFromChildData(data);
        List<NodeEvent> events = NodeEvent.generateEvents(properties, names, type);

        if (events.isEmpty()) {

View on GitHub (pinned to fa8dc99126)

Solutions

  1. Set zkConnectString (e.g. listener.setZkConnectString("host:2181")) or inject a configured Curator client via setClient(...).
  2. Double-check property names in Spring/yaml (zkConnectString vs zkConnect) and confirm the profile loading them is active.
  3. Add a startup validation that both path and urlTemplate are also set, since checkParameters validates those next.

Example fix

// before
ZookeeperNodeListener l = new ZookeeperNodeListener();
l.setPath("/druid/ha");
l.setUrlTemplate("jdbc:mysql://{host}:{port}/db");
l.start(); // throws: zk client/connect string missing

// after
l.setZkConnectString("zk1:2181,zk2:2181");
l.setPath("/druid/ha");
l.setUrlTemplate("jdbc:mysql://{host}:{port}/db");
l.start();
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight before start():
ZookeeperNodeListener z = (ZookeeperNodeListener) listener;
if (z.getClient() == null && (z.getZkConnectString() == null || z.getZkConnectString().isEmpty())) {
    throw new IllegalStateException("provide a Curator client or setZkConnectString(...)");
}

Type guard

public static boolean zkConfigured(ZookeeperNodeListener z) {
    return z.getClient() != null || (z.getZkConnectString() != null && !z.getZkConnectString().isEmpty());
}

Prevention

When it happens

Trigger: Calling start()/refresh()/init() on a ZookeeperNodeListener whose client field is null and whose zkConnectString is empty or null — i.e. neither programmatic client injection nor connection-string configuration was done.

Common situations: Misconfigured HA DataSource where the zkConnect property was typo'd or omitted; switching from injecting a Curator client to connection-string config but leaving both unset; profile-specific config not loaded so the property is blank.

Related errors


AI-assisted analysis of alibaba/druid@fa8dc99126 (2026-08-14). Data as JSON: /api/errors/d32e2adca0bd62eb. Report an issue: GitHub.