alibaba/druid · error · DruidRuntimeException
Please set the urlTemplate.
Error message
Please set the urlTemplate.
What it means
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.
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.
Example fix
// before
ZookeeperNodeListener l = new ZookeeperNodeListener();
l.setZkConnectString("zk1:2181");
l.setPath("/druid/ha");
l.start(); // throws: urlTemplate missing
// after
l.setZkConnectString("zk1:2181");
l.setPath("/druid/ha");
l.setUrlTemplate("jdbc:mysql://{host}:{port}/orders");
l.start(); Defensive patterns
Strategy: validation
Validate before calling
ZookeeperNodeListener z = (ZookeeperNodeListener) listener;
if (z.getUrlTemplate() == null || z.getUrlTemplate().isEmpty()) {
throw new IllegalStateException("set urlTemplate, e.g. jdbc:mysql://{host}:{port}/db");
}
if (!z.getUrlTemplate().contains("{host}") || !z.getUrlTemplate().contains("{port}")) {
throw new IllegalStateException("urlTemplate must contain {host} and {port} placeholders");
} Type guard
public static boolean templateConfigured(ZookeeperNodeListener z) {
String t = z.getUrlTemplate();
return t != null && !t.isEmpty() && t.contains("{host}") && t.contains("{port}");
} Prevention
- 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.
When it happens
Trigger: Starting a ZookeeperNodeListener whose urlTemplate field is null or empty — setUrlTemplate(...) was never called or received a blank string.
Common situations: 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.
Related errors
- Please set the ZooKeeper node path.
- ZK Client is NULL, Please set the zkConnectString.
- No Observer(such as PoolUpdater) specified.
- Cannot load remote config file from the
- {className}
AI-assisted analysis of alibaba/druid@fa8dc99126 (2026-08-14).
Data as JSON: /api/errors/d0ea69d5fe06dbf3.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/com/alibaba/druid/pool/ha/node/ZookeeperNodeListener.java:185
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()) {
return;
}
if (type == NodeEventTypeEnum.ADD) {
getProperties().putAll(properties);
} else {
for (String n : properties.stringPropertyNames()) {View on GitHub (pinned to fa8dc99126)