apache/dolphinscheduler · error · RegistryException

Failed to subscribe listener for key:

Error message

Failed to subscribe listener for key: 

What it means

ZookeeperRegistry.subscribe() wraps any failure while starting a Curator TreeCache for the subscribed path in a RegistryException. The TreeCache is created, the listener adapter is attached, and treeCache.start() performs an initial sync of the subtree from the ZooKeeper server; if that sync or setup fails, the cache entry is rolled back out of treeCacheMap and this error is thrown.

Source

Thrown at dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-zookeeper/src/main/java/org/apache/dolphinscheduler/plugin/registry/zookeeper/ZookeeperRegistry.java:149

            }
        } catch (RegistryException e) {
            throw e;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RegistryException(
                    String.format("Cannot connect to registry in %s s", timeout.getSeconds()), e);
        }
    }

    @Override
    public void subscribe(final String path, final SubscribeListener listener) {
        final TreeCache treeCache = treeCacheMap.computeIfAbsent(path, $ -> new TreeCache(client, path));
        treeCache.getListenable().addListener(new ZookeeperTreeCacheListenerAdapter(path, listener));
        try {
            treeCache.start();
        } catch (Exception e) {
            treeCacheMap.remove(path);
            throw new RegistryException("Failed to subscribe listener for key: " + path, e);
        }
    }

    @Override
    public String get(String key) {
        try {
            return new String(client.getData().forPath(key), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RegistryException("zookeeper get data error", e);
        }
    }

    @Override
    public boolean exists(String key) {
        try {
            return null != client.checkExists().forPath(key);
        } catch (Exception e) {
            throw new RegistryException("zookeeper check key is existed error", e);

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Verify ZooKeeper connectivity with `echo ruok | nc <host> 2181` and check registry.zookeeper.connect-string, auth and session-timeout settings in dolphinscheduler-common config
  2. Check server ACLs/ZooKeeper authorization config so the client user can read the subscribed path
  3. Ensure the subscribed key is a valid absolute ZNode path (starts with '/', no empty segments or null characters)
  4. Retry the subscribe after the session recovers — Curator will re-establish the session; restart the master/worker if the client is stuck in a dead session
  5. Inspect the wrapped cause `e` in the RegistryException — KeeperException codes (CONNECTIONLOSS, SESSIONEXPIRED, AUTHFAILED, BADARGUMENTS) pinpoint the root cause

Example fix

// before
registry.subscribe("/nodes/" + nullHost, listener);
// after
String path = "/nodes/" + host;
if (host == null || host.isEmpty()) { throw new IllegalArgumentException("host required"); }
registry.subscribe(path, listener);
Defensive patterns

Strategy: try-catch

Validate before calling

// validate path before subscribing
if (key == null || !key.startsWith("/") || key.contains("//")) {
    throw new IllegalArgumentException("invalid registry key: " + key);
}
if (!isZkReachable(zkQuorum)) { /* check before subscribe */ }

Try / catch

try {
    registry.subscribe(key, listener);
} catch (RegistryException e) {
    logger.error("subscribe failed for {}: {}", key, e.getCause() == null ? e : e.getCause().getMessage(), e);
    if (e.getCause() instanceof KeeperException.ConnectionLossException || e.getCause() instanceof KeeperException.SessionExpiredException) {
        scheduleRetrySubscribe(key, listener); // retry after session recovery
    }
}

Prevention

When it happens

Trigger: Calling subscribe(key, listener) when the ZooKeeper session is down or expired, when the client cannot reach the ensemble (connect timeout), when authentication/ACLs deny reading the path, or when the path contains invalid characters (e.g. empty key or key with null bytes) causing TreeCache.start() to fail.

Common situations: ZooKeeper ensemble unreachable after network partition or misquoted connect string (e.g. wrong port in registry.zookeeper.connect-string); session expired due to long GC pause; SASL/ACL misconfiguration after tightening server permissions; subscribing to a malformed key built from a null/empty task parameter.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/b57f9317792dedab. Report an issue: GitHub.