apache/druid · warning

Unannouncing non-empty path

Error message

Unannouncing non-empty path[%s]

What it means

PathChildrenAnnouncer.unannounce performs a transactional delete of the announced path and its parent. KeeperException.NotEmptyException means the parent znode could not be removed because it still contains children (other announced children under the same parent). The class deliberately logs a warning rather than throwing since removing non-empty parents is expected when multiple children share a parent.

Solutions

  1. Verify that sibling child znodes under the parent are legitimately still announced; if so, the warning is expected and can be ignored.
  2. Stop all child announcers before stopping the shared parent announcer so the parent delete succeeds.
  3. Inspect the path with the ZK CLI to identify which children remain and who created them.
  4. Clean up stale children left by crashed processes if no live process owns them.

Example fix

// before
childAnnouncer.stop(); // only one child stopped; parent still has others
// after
childAnnouncer1.stop();
childAnnouncer2.stop();
parentAnnouncer.stop(); // parent now empty and deletable
Defensive patterns

Strategy: validation

Validate before calling

// confirm no live siblings remain under the parent before stopping the last announcer
List<String> children = zooKeeper.getChildren(parentPath, false);
if (children.size() > 1) { /* expected NotEmpty warning */ }

Prevention

When it happens

Trigger: Calling stop() (which invokes unannounce) on a PathChildrenAnnouncer whose parent path still holds child znodes — e.g. several children announced under one parent and only one child announcer is being stopped.

Common situations: Multiple announcements under a common directory (coordinator/overlord service discovery paths), incomplete prior shutdowns leaving orphan children, or overlapping announcers from different Druid processes sharing a parent.

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/0d847f84abd75eb7. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/curator/announcement/PathChildrenAnnouncer.java:429

    final String parentPath = pathAndNode.getPath();

    final ConcurrentMap<String, byte[]> subPaths = announcements.get(parentPath);

    if (subPaths == null || subPaths.remove(pathAndNode.getNode()) == 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(PathChildrenCache cache)
  {
    try {
      cache.start();
    }
    catch (Throwable e) {
      throw CloseableUtils.closeAndWrapInCatch(e, cache);
    }
  }

  private void createPath(String parentPath, boolean removeParentsIfCreated)
  {

View on GitHub (pinned to 9b90983fd2)