apache/pulsar · error · MetadataStoreException
Failed to set data for ${path}
Error message
Failed to set data for ${path} What it means
BaseResources.set performs a read-modify-update through the cache and blocks until completion; failures (store errors, optimistic-concurrency retries exhausted, timeout, interruption) are converted into MetadataStoreException('Failed to set data for <path>'). It means a policy/resource update could not be persisted at that path.
Source
Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/broker/resources/BaseResources.java:159
protected CompletableFuture<Optional<T>> getAsync(String path) {
return cache.get(path);
}
protected CompletableFuture<Optional<T>> refreshAndGetAsync(String path) {
return store.sync(path).thenCompose(___ -> {
cache.invalidate(path);
return cache.get(path);
});
}
protected void set(String path, Function<T, T> modifyFunction) throws MetadataStoreException {
try {
setAsync(path, modifyFunction).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 set data for " + path, e);
}
}
protected CompletableFuture<Void> setAsync(String path, Function<T, T> modifyFunction) {
return cache.readModifyUpdate(path, modifyFunction).thenApply(__ -> null);
}
protected void setWithCreate(String path, Function<Optional<T>, T> createFunction) throws MetadataStoreException {
try {
setWithCreateAsync(path, createFunction).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 set/create " + path, e);
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Retry the update if caused by concurrent modification (the cache retries, but heavy contention can still fail)
- Check metadata store write access and quorum health
- Increase operationTimeoutSec for large policy documents
- Serialize admin updates for the same resource to reduce version conflicts
Example fix
// before
nsResources.set(path, policies -> { policies.auth_policies.put(...); return policies; });
// after
try {
nsResources.set(path, policies -> { policies.auth_policies.put(...); return policies; });
} catch (MetadataStoreException e) {
if (e.getCause() instanceof MetadataStoreException.BadVersionException) {
// retry once after re-reading current policies
} else { throw e; }
} Defensive patterns
Strategy: retry
Validate before calling
if (!resources.exists(path)) throw new IllegalStateException("Cannot set: path missing " + path); Try / catch
try { resources.set(path, modifier); }
catch (MetadataStoreException e) {
if (e.getCause() instanceof MetadataStoreException.BadVersionException) { /* re-read and retry */ }
else throw e;
} Prevention
- Minimize concurrent admin writers per resource
- Retry version-conflict failures with fresh reads
- Ensure store quorum health before bulk updates
When it happens
Trigger: Calling set(path, modifyFunction) when the readModifyUpdate fails due to store write errors, version/BadVersion conflicts after retries, operation timeout, or interruption.
Common situations: Concurrent admin updates racing on the same path; metadata store read-only or quorum loss; ZooKeeper BadVersionException due to simultaneous writers; timeout too small during heavy update traffic.
Related errors
- Failed to set/create ${path}
- Concurrent modification
- Failed to get children of ${path}
- Failed to get data from ${path}
- Failed to create ${path}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/072e4907f3261da8.
Report an issue: GitHub.