apache/pulsar · error · RestException
Concurrent modification
Error message
Concurrent modification
What it means
grantPermissionsAsync detected a concurrent modification of the topic's authorization policies while writing to the metadata store (e.g., a NotFound or IllegalState race); historically mapped from grantPermissionAsync failures to keep client compatibility.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:258
.log("Successfully granted access for role on topic"))
.exceptionally(ex -> {
Throwable realCause = FutureUtil.unwrapCompletionException(ex);
//The IllegalArgumentException and the IllegalStateException were historically thrown by the
// grantPermissionAsync method, so we catch them here to ensure backwards compatibility.
if (realCause instanceof MetadataStoreException.NotFoundException
|| realCause instanceof IllegalArgumentException) {
log.warn()
.attr("topic", topicUri)
.exception(realCause)
.log("Failed to set permissions for topic: Namespace does not exist");
throw new RestException(Status.NOT_FOUND, "Topic's namespace does not exist");
} else if (realCause instanceof MetadataStoreException.BadVersionException
|| realCause instanceof IllegalStateException) {
log.warn()
.attr("topic", topicUri)
.exceptionMessage(realCause)
.log("Failed to set permissions for topic");
throw new RestException(Status.CONFLICT, "Concurrent modification");
} else {
log.error()
.attr("topic", topicUri)
.exceptionMessage(realCause)
.log("Failed to get permissions for topic");
throw new RestException(realCause);
}
});
} else {
String msg = "Authorization is not enabled";
return FutureUtil.failedFuture(new RestException(Status.NOT_IMPLEMENTED, msg));
}
}
protected void internalGrantPermissionsOnTopic(final AsyncResponse asyncResponse, String role,
Set<AuthAction> actions) {
// This operation should be reading from zookeeper and it should be allowed without having admin privileges
CompletableFuture<Void> validateAccessForTenantCf = validateAdminAccessForTenantAsync(namespaceName.getTenant())View on GitHub (pinned to 820761864e)
Solutions
- Retry the grant — the conflict is typically transient
- Serialize concurrent permission changes on the same topic
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java:258 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/c707b3414de5f93a.
Report an issue: GitHub.