{"record":{"id":"98fddb5cd27d37ac","repo":"apache/pulsar","slug":"unauthorized-to-validatetopicoperation-for-operati","errorCode":null,"errorMessage":"Unauthorized to validateTopicOperation for operation [%s] on topic [%s]","messagePattern":"Unauthorized to validateTopicOperation for operation \\[(.+?)\\] on topic \\[(.+?)\\]","errorType":"http","errorClass":"RestException","httpStatus":401,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java","lineNumber":1273,"sourceCode":"       return validateTopicOperationAsync(topicName, operation, null);\n    }\n\n    public CompletableFuture<Void> validateTopicOperationAsync(TopicName topicName,\n                                                               TopicOperation operation, String subscription) {\n        if (pulsar().getConfiguration().isAuthenticationEnabled()\n                && pulsar().getBrokerService().isAuthorizationEnabled()) {\n            if (!isClientAuthenticated(clientAppId())) {\n                return FutureUtil.failedFuture(\n                        new RestException(Status.UNAUTHORIZED, \"Need to authenticate to perform the request\"));\n            }\n\n            AuthenticationDataSource authData = clientAuthData();\n            authData.setSubscription(subscription);\n            return pulsar().getBrokerService().getAuthorizationService()\n                    .allowTopicOperationAsync(topicName, operation, originalPrincipal(), clientAppId(), authData)\n                    .thenAccept(isAuthorized -> {\n                        if (!isAuthorized) {\n                            throw new RestException(Status.UNAUTHORIZED, String.format(\n                                    \"Unauthorized to validateTopicOperation for operation [%s] on topic [%s]\",\n                                    operation.toString(), topicName));\n                        }\n                    });\n        } else {\n            return CompletableFuture.completedFuture(null);\n        }\n    }\n\n    public <T> T sync(Supplier<CompletableFuture<T>> supplier) {\n        try {\n            return supplier.get().get(config().getMetadataStoreOperationTimeoutSeconds(), SECONDS);\n        } catch (ExecutionException | TimeoutException ex) {\n            Throwable realCause = FutureUtil.unwrapCompletionException(ex);\n            if (realCause instanceof WebApplicationException) {\n                throw (WebApplicationException) realCause;\n            } else {\n                throw new RestException(realCause);","sourceCodeStart":1255,"sourceCodeEnd":1291,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java#L1255-L1291","documentation":"Authorization guard for topic operations (produce/consume/etc.): the client's role lacks the specific topic operation permission; returned as an authorization failure from validateTopicOperationAsync.","triggerScenarios":"Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java:1273 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["grant permissions on the topic for the role and operation","Check authentication is enabled correctly so the role is resolved"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}