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
- Verify that sibling child znodes under the parent are legitimately still announced; if so, the warning is expected and can be ignored.
- Stop all child announcers before stopping the shared parent announcer so the parent delete succeeds.
- Inspect the path with the ZK CLI to identify which children remain and who created them.
- 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
- Stop all child announcers sharing a parent before stopping the parent announcer.
- Treat this warning as expected whenever siblings are still announced.
- Clean up stale children from crashed processes during maintenance.
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
- Unannouncing non-empty path
- can't start.
- can't stop.
- can't stop.
- Could not close old leader latch; continuing with new one…
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)