apache/shenyu · error · ShenyuException
zookeeper url: is is error.
Error message
zookeeper url:${zookeeperUrl} is is error. What it means
IngressReconciler.getZookeeperUrl extracts and normalizes the ZooKeeper address from the ShenyuCluster custom resource. Before returning, it validates the host with isCompleteHost; if the URL does not have a complete host it throws ShenyuException('zookeeper url:... is is error.'). The awkward double 'is' is just the message text.
Solutions
- Fix the zookeeper url in the ShenyuCluster custom resource to a complete host:port, e.g. 'zookeeper-client:2181' or '10.0.0.5:2181'
- Check the controller log line 'Please enter the correct zookeeperUrl address' and the echoed url value
- Compare with the format other working ShenyuCluster resources use
- kubectl edit the ShenyuCluster resource and correct the spec field
Example fix
// before (ShenyuCluster spec) zookeeperK8sUrl: zk:2181 // after zookeeperK8sUrl: zookeeper-client.default.svc.cluster.local:2181
Defensive patterns
Strategy: validation
Validate before calling
String zkUrl = cluster.getSpec().getZookeeperK8sUrl();
boolean looksComplete = zkUrl != null && zkUrl.matches("^[a-zA-Z0-9.-]+(:\\d{1,5})$");
if (!looksComplete) throw new IllegalArgumentException("fix zookeeperK8sUrl in ShenyuCluster spec"); Try / catch
try {
reconciler.getZookeeperUrl(...);
} catch (ShenyuException e) {
LOG.error("ShenyuCluster spec has invalid zookeeper url: {}", e.getMessage());
// surface the error in the CR status
} Prevention
- Use complete host:port values in the ShenyuCluster spec
- Validate CR fields with a webhook before acceptance
- Copy URL formats from working ShenyuCluster resources
- Prefer fully qualified service DNS names in k8s
When it happens
Trigger: A ShenyuCluster spec (zookeeperK8sUrl) whose zookeeper address fails the isCompleteHost check — missing host, missing port, or malformed address — passed through getZookeeperUrl via zookeeperUrl.
Common situations: Typo in the ShenyuCluster CR spec, using a k8s service short name where a full host:port is expected, copying a 'zk-0.zk-headless:2181' style URL where validation expects a fully qualified host.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- failed to add curator cache.
- renew master fail
- Access to private or internal IP addresses is not allowed
- Access to sensitive ports is not allowed
- Cannot resolve host: " + host
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/9eef7d2126859b9f.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-kubernetes-controller/src/main/java/org/apache/shenyu/k8s/reconciler/IngressReconciler.java:334
List<V1EndpointSubset> subsets = v1Endpoints.getSubsets();
if (Objects.isNull(subsets) || CollectionUtils.isEmpty(subsets)) {
LOG.info("Endpoints do not have subsets");
} else {
for (V1EndpointSubset subset : subsets) {
List<V1EndpointAddress> addresses = subset.getAddresses();
if (Objects.isNull(addresses) || addresses.isEmpty()) {
continue;
}
for (V1EndpointAddress address : addresses) {
zookeeperUrl = address.getIp();
}
}
}
}
}
if (!isCompleteHost(zookeeperUrl)) {
LOG.info("Please enter the correct zookeeperUrl address");
throw new ShenyuException("zookeeper url:" + zookeeperUrl + " is is error.");
}
zookeeperUrl = replaceZookeeperHost(zookeeperK8sUrl, zookeeperUrl);
return zookeeperUrl;
}
/**
* Check whether the IngressClass is shenyu, check the annotation first.
*
* @param v1Ingress v1Ingress
* @return boolean
*/
private boolean checkIngressClass(final V1Ingress v1Ingress) {
if (Objects.nonNull(v1Ingress.getMetadata())) {
Map<String, String> annotations = v1Ingress.getMetadata().getAnnotations();
if (Objects.nonNull(annotations)
&& Objects.nonNull(annotations.get(IngressConstants.K8S_INGRESS_CLASS_ANNOTATION_KEY))) {
return IngressConstants.SHENYU_INGRESS_CLASS.equals(annotations.get(IngressConstants.K8S_INGRESS_CLASS_ANNOTATION_KEY));
} else {View on GitHub (pinned to 567142e072)