{"record":{"id":"d32e2adca0bd62eb","repo":"alibaba/druid","slug":"zk-client-is-null-please-set-the-zkconnectstring","errorCode":null,"errorMessage":"ZK Client is NULL, Please set the zkConnectString.","messagePattern":"ZK Client is NULL, Please set the zkConnectString\\.","errorType":"exception","errorClass":"DruidRuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/alibaba/druid/pool/ha/node/ZookeeperNodeListener.java","lineNumber":179,"sourceCode":"     */\n    @Override\n    public List<NodeEvent> refresh() {\n        lock.lock();\n        try {\n            Properties properties = getPropertiesFromCache();\n            List<NodeEvent> events = NodeEvent.getEventsByDiffProperties(getProperties(), properties);\n            if (events != null && !events.isEmpty()) {\n                setProperties(properties);\n            }\n            return events;\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    private void checkParameters() {\n        if (client == null && StringUtils.isEmpty(zkConnectString)) {\n            throw new DruidRuntimeException(\"ZK Client is NULL, Please set the zkConnectString.\");\n        }\n        if (StringUtils.isEmpty(path)) {\n            throw new DruidRuntimeException(\"Please set the ZooKeeper node path.\");\n        }\n        if (StringUtils.isEmpty(urlTemplate)) {\n            throw new DruidRuntimeException(\"Please set the urlTemplate.\");\n        }\n    }\n\n    private void updateSingleNode(PathChildrenCacheEvent event, NodeEventTypeEnum type) {\n        ChildData data = event.getData();\n        String nodeName = getNodeName(data);\n        List<String> names = new ArrayList<String>();\n        names.add(getPrefix() + \".\" + nodeName);\n        Properties properties = getPropertiesFromChildData(data);\n        List<NodeEvent> events = NodeEvent.generateEvents(properties, names, type);\n\n        if (events.isEmpty()) {","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/alibaba/druid/blob/fa8dc9912637a2f729eef9f55356621fec18d40e/core/src/main/java/com/alibaba/druid/pool/ha/node/ZookeeperNodeListener.java#L161-L197","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set zkConnectString (e.g. listener.setZkConnectString(\"host:2181\")) or inject a configured Curator client via setClient(...).","Double-check property names in Spring/yaml (zkConnectString vs zkConnect) and confirm the profile loading them is active.","Add a startup validation that both path and urlTemplate are also set, since checkParameters validates those next."],"exampleFix":"// before\nZookeeperNodeListener l = new ZookeeperNodeListener();\nl.setPath(\"/druid/ha\");\nl.setUrlTemplate(\"jdbc:mysql://{host}:{port}/db\");\nl.start(); // throws: zk client/connect string missing\n\n// after\nl.setZkConnectString(\"zk1:2181,zk2:2181\");\nl.setPath(\"/druid/ha\");\nl.setUrlTemplate(\"jdbc:mysql://{host}:{port}/db\");\nl.start();","handlingStrategy":"validation","validationCode":"// pre-flight before start():\nZookeeperNodeListener z = (ZookeeperNodeListener) listener;\nif (z.getClient() == null && (z.getZkConnectString() == null || z.getZkConnectString().isEmpty())) {\n    throw new IllegalStateException(\"provide a Curator client or setZkConnectString(...)\");\n}","typeGuard":"public static boolean zkConfigured(ZookeeperNodeListener z) {\n    return z.getClient() != null || (z.getZkConnectString() != null && !z.getZkConnectString().isEmpty());\n}","tryCatchPattern":null,"preventionTips":["Set zkConnectString explicitly even when injecting a client, to ease debugging.","Validate config in a boot sanity-check bean.","Confirm the active Spring profile actually loads the zk properties."],"tags":["ha-datasource","zookeeper","configuration","node-listener"],"backgroundTag":null,"analyzedSha":"fa8dc9912637a2f729eef9f55356621fec18d40e","analyzedAt":"2026-08-14T04:55:06.789Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}