{"record":{"id":"d0ea69d5fe06dbf3","repo":"alibaba/druid","slug":"please-set-the-urltemplate","errorCode":null,"errorMessage":"Please set the urlTemplate.","messagePattern":"Please set the urlTemplate\\.","errorType":"exception","errorClass":"DruidRuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/alibaba/druid/pool/ha/node/ZookeeperNodeListener.java","lineNumber":185,"sourceCode":"            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()) {\n            return;\n        }\n        if (type == NodeEventTypeEnum.ADD) {\n            getProperties().putAll(properties);\n        } else {\n            for (String n : properties.stringPropertyNames()) {","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/alibaba/druid/blob/fa8dc9912637a2f729eef9f55356621fec18d40e/core/src/main/java/com/alibaba/druid/pool/ha/node/ZookeeperNodeListener.java#L167-L203","documentation":"ZookeeperNodeListener.checkParameters() throws this when urlTemplate is empty/null. The template (e.g. jdbc:mysql://{host}:{port}/db) is used to synthesize a JDBC URL for each child node value, so the listener can feed real DataSource URLs to the PoolUpdater. Without it the HA pool cannot materialize new node connections.","triggerScenarios":"Starting a ZookeeperNodeListener whose urlTemplate field is null or empty — setUrlTemplate(...) was never called or received a blank string.","commonSituations":"Config key typo (e.g. url-template vs urlTemplate); property omitted in yaml; template missing the {host}/{port} placeholders which a separate validation may also reject downstream.","solutions":["Call listener.setUrlTemplate(\"jdbc:mysql://{host}:{port}/yourdb\") — must contain the {host} and {port} placeholders the listener substitutes from each znode value.","Confirm the JDBC scheme prefix matches a driver that is on the classpath, or the resulting URL will fail later when a connection is opened.","Validate the template in a startup assertion so misconfiguration surfaces at boot, not on the first node event."],"exampleFix":"// before\nZookeeperNodeListener l = new ZookeeperNodeListener();\nl.setZkConnectString(\"zk1:2181\");\nl.setPath(\"/druid/ha\");\nl.start(); // throws: urlTemplate missing\n\n// after\nl.setZkConnectString(\"zk1:2181\");\nl.setPath(\"/druid/ha\");\nl.setUrlTemplate(\"jdbc:mysql://{host}:{port}/orders\");\nl.start();","handlingStrategy":"validation","validationCode":"ZookeeperNodeListener z = (ZookeeperNodeListener) listener;\nif (z.getUrlTemplate() == null || z.getUrlTemplate().isEmpty()) {\n    throw new IllegalStateException(\"set urlTemplate, e.g. jdbc:mysql://{host}:{port}/db\");\n}\nif (!z.getUrlTemplate().contains(\"{host}\") || !z.getUrlTemplate().contains(\"{port}\")) {\n    throw new IllegalStateException(\"urlTemplate must contain {host} and {port} placeholders\");\n}","typeGuard":"public static boolean templateConfigured(ZookeeperNodeListener z) {\n    String t = z.getUrlTemplate();\n    return t != null && !t.isEmpty() && t.contains(\"{host}\") && t.contains(\"{port}\");\n}","tryCatchPattern":null,"preventionTips":["Ensure urlTemplate includes {host} and {port} placeholders.","Verify the JDBC scheme prefix matches a driver on the classpath.","Validate all three HA parameters (zk, path, template) in one startup assertion."],"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"}