apache/druid · warning

Unannouncing non-empty path

Error message

Unannouncing non-empty path[%s]

What it means

In NodeAnnouncer.unannounce, after a successful ZK delete transaction, a subsequent transactional delete of the parent path failed with KeeperException.NotEmptyException, meaning the parent znode still holds child znodes. The library logs a warning instead of failing because partial cleanup of a non-empty path is usually benign (other announcements still live there).

Solutions

  1. Ensure the full announcement subtree is deleted: call unannounce on the exact paths created by announce, and only delete parent nodes you own.
  2. Check for other announcements/children under the path with the ZK CLI (zkCli.sh ls /path) before assuming cleanup failure is a bug.
  3. If this is a graceful shutdown, verify the CuratorFramework and NodeAnnouncer are closed in the correct order so child unannouncements complete first.
  4. If the path is stale garbage, remove it manually with the ZK CLI after confirming no live processes depend on it.

Example fix

// before
announcer.unannounce("/druid/cluster/coordinator"); // deletes only the parent, children remain
// after
announcer.unannounce("/druid/cluster/coordinator/instance1"); // delete leaf znodes first
announcer.unannounce("/druid/cluster/coordinator"); // then the parent
Defensive patterns

Strategy: validation

Validate before calling

// ensure only leaf znodes this process created are unannounced
if (zooKeeper.getChildren(path, false).isEmpty()) {
  announcer.unannounce(path);
} else {
  // unannounce children first or skip parent delete
}

Prevention

When it happens

Trigger: Calling unannounce(path) (via closeResources) when the znode at `path` has children — e.g. the announced node also created child znodes, or multiple announcers share a parent path and only some were unannounced before the parent delete was attempted.

Common situations: Shared ZK paths (e.g. multiple processes or multiple announcements under one parent directory), abrupt shutdown where children were created after the initial announcement, or stale hierarchy left from a previous run that wasn't fully cleaned up.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/215188c4420f506c. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/curator/announcement/NodeAnnouncer.java:368

      final byte[] value = announcedPaths.remove(path);

      if (value == null) {
        log.debug("Path[%s] not announced, cannot unannounce.", path);
        return;
      }
    }

    log.info("unannouncing [%s]", path);

    try {
      CuratorOp deleteOp = curator.transactionOp().delete().forPath(path);
      curator.transaction().forOperations(deleteOp);
    }
    catch (KeeperException.NoNodeException e) {
      log.info("Unannounced node[%s] that does not exist.", path);
    }
    catch (KeeperException.NotEmptyException e) {
      log.warn("Unannouncing non-empty path[%s]", path);
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  private void startCache(CuratorCache cache)
  {
    try {
      cache.start();
    }
    catch (Throwable e) {
      throw CloseableUtils.closeAndWrapInCatch(e, cache);
    }
  }

  @GuardedBy("toAnnounce")
  private void createPath(String parentPath, boolean removeParentsIfCreated)

View on GitHub (pinned to 9b90983fd2)