apache/pulsar · error · MetadataStoreException

Failed to delete ${path}

Error message

Failed to delete ${path}

What it means

BaseResources.delete removes a metadata path synchronously; unexpected causes, timeouts, and interruptions are wrapped as MetadataStoreException('Failed to delete <path>'). Often the cause is a not-empty or not-found error from the metadata store.

Source

Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/resources/BaseResources.java:204

            throw (e.getCause() instanceof MetadataStoreException) ? (MetadataStoreException) e.getCause()
                    : new MetadataStoreException(e.getCause());
        } catch (Exception e) {
            throw new MetadataStoreException("Failed to create " + path, e);
        }
    }

    protected CompletableFuture<Void> createAsync(String path, T data) {
        return cache.create(path, data);
    }

    protected void delete(String path) throws MetadataStoreException {
        try {
            deleteAsync(path).get(operationTimeoutSec, TimeUnit.SECONDS);
        } catch (ExecutionException e) {
            throw (e.getCause() instanceof MetadataStoreException) ? (MetadataStoreException) e.getCause()
                    : new MetadataStoreException(e.getCause());
        } catch (Exception e) {
            throw new MetadataStoreException("Failed to delete " + path, e);
        }
    }

    protected CompletableFuture<Void> deleteAsync(String path) {
        return cache.delete(path);
    }

    protected CompletableFuture<Void> deleteIfExistsAsync(String path) {
        log.info().attr("path", path).log("Deleting path");
        CompletableFuture<Void> future = new CompletableFuture<>();
        cache.delete(path).whenComplete((ignore, ex) -> {
            if (ex != null && ex.getCause() instanceof MetadataStoreException.NotFoundException) {
                log.info().attr("path", path).log("Path did not exist in metadata store");
                future.complete(null);
            } else if (ex != null) {
                log.info().attr("path", path).exception(ex).log("Failed to delete path from metadata store");
                future.completeExceptionally(ex);
            } else {

View on GitHub (pinned to 820761864e)

Solutions

  1. Delete child nodes first or use the recursive delete path in the admin resources layer
  2. Check the cause: not-found may be benign — treat idempotently
  3. Verify metadata store health and session state
  4. Increase operationTimeoutSec for deep trees

Example fix

// before
resources.delete(path);
// after
try { resources.delete(path); }
catch (MetadataStoreException e) {
    if (e.getCause() instanceof MetadataStoreException.NotFoundException) { /* already gone */ }
    else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (resources.exists(path) && !resources.getChildren(path).isEmpty()) throw new IllegalStateException("Node has children: " + path);

Try / catch

try { resources.delete(path); }
catch (MetadataStoreException e) {
    if (causeIsNotFound(e.getCause())) { /* already deleted: treat as success */ }
    else throw e;
}

Prevention

When it happens

Trigger: Calling delete(path) when the node has children (non-recursive delete rejected), the node was already deleted, the store is unavailable, or the timeout elapses.

Common situations: Deleting a parent namespace/tenant node that still has children; concurrent deletion by another admin; ZooKeeper session expired; slow store exceeding timeout.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/3fcdc4b69b5e18f2. Report an issue: GitHub.