apache/pulsar · error · RestException
Need to authenticate to perform the request
Error message
Need to authenticate to perform the request
What it means
If both authentication and authorization are enabled, validateAdminAccessForTenantAsync requires an authenticated client identity. When clientAppId is null/blank (unauthenticated request), it throws RestException with HTTP 403 'Need to authenticate to perform the request' — you must authenticate before tenant-admin authorization can be evaluated.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/web/PulsarWebResource.java:343
protected CompletableFuture<Void> validateAdminAccessForTenantAsync(
PulsarService pulsar, String clientAppId,
String originalPrincipal, String tenant,
AuthenticationDataSource authenticationData) {
log.debug()
.attr("tenant", tenant)
.attr("authenticated", (isClientAuthenticated(clientAppId)))
.attr("role", clientAppId)
.log("check admin access on tenant");
return pulsar.getPulsarResources().getTenantResources().getTenantAsync(tenant)
.thenCompose(tenantInfoOptional -> {
if (tenantInfoOptional.isEmpty()) {
throw new RestException(Status.NOT_FOUND, "Tenant does not exist");
}
TenantInfo tenantInfo = tenantInfoOptional.get();
if (pulsar.getConfiguration().isAuthenticationEnabled() && pulsar.getConfiguration()
.isAuthorizationEnabled()) {
if (!isClientAuthenticated(clientAppId)) {
throw new RestException(Status.FORBIDDEN, "Need to authenticate to perform the request");
}
validateOriginalPrincipal(clientAppId, originalPrincipal);
if (pulsar.getConfiguration().getProxyRoles().contains(clientAppId)) {
AuthorizationService authorizationService =
pulsar.getBrokerService().getAuthorizationService();
return authorizationService.isTenantAdmin(tenant, clientAppId, tenantInfo,
authenticationData)
.thenCompose(isTenantAdmin -> {
if (!isTenantAdmin) {
return authorizationService.isSuperUser(clientAppId, authenticationData)
.thenCombine(authorizationService.isSuperUser(originalPrincipal,
authenticationData),
(proxyAuthorized, originalPrincipalAuthorized) -> {
if (!proxyAuthorized || !originalPrincipalAuthorized) {
throw new RestException(Status.UNAUTHORIZED,
String.format("Proxy not authorized to access "
+ "resource (proxy:%s,original:%s)"
, clientAppId, originalPrincipal));View on GitHub (pinned to 820761864e)
Solutions
- Send valid credentials (e.g. Authorization: Bearer <token>) with the request
- Fix the client's auth plugin configuration (provider, token/credentials file, issuer URL)
- Check broker logs/authentication plugin to see why no role was derived from the presented credentials
- If the endpoint is intentionally open, adjust broker authenticationEnabled — not recommended for admin APIs
Example fix
// before curl http://broker:8080/admin/v2/tenants/mytenant // after curl -H "Authorization: Bearer $ADMIN_TOKEN" http://broker:8080/admin/v2/tenants/mytenant
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side pre-check: PulsarAdmin built without Authentication will send no credentials
if (pulsarAdmin.getClientConfig() == null || !hasAuthPlugin(pulsarAdmin)) {
throw new IllegalStateException("PulsarAdmin must be configured with an Authentication provider");
} Try / catch
try {
admin.tenants().getTenant(tenant);
} catch (PulsarAdminException e) {
if (e.getStatusCode() == 403) {
// refresh credentials / reconfigure the auth plugin
}
throw e;
} Prevention
- Always configure an Authentication provider on PulsarAdmin in secured clusters
- Refresh/rotate tokens before expiry in long-running admin jobs
- Check broker authenticationEnabled/authorizationEnabled flags match your client setup
When it happens
Trigger: Calling a tenant-admin endpoint without credentials while broker has authenticationEnabled=true and authorizationEnabled=true; client sends no/malformed Authorization header so the auth plugin yields no role; anonymous access to a tenant-scoped endpoint.
Common situations: curl/scripts missing the auth token; expired token rejected in a way that leaves no principal; misconfigured client auth plugin (wrong provider/parameters); broker auth enabled after clients were built without auth support.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid combination of Original principal cannot be empty if
- Time-out while checking authorization
- Failed to get permissions
- Proxy not authorized for super-user operation (proxy:%s)
- Original principal not authorized for super-user operation (
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/8fd99eb71c81de46.
Report an issue: GitHub.