{"record":{"id":"cf3054b4fe67b566","repo":"apache/pulsar","slug":"authentication-required","errorCode":null,"errorMessage":"Authentication required","messagePattern":"Authentication required","errorType":"http","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java","lineNumber":163,"sourceCode":"                throw new AuthenticationException(\"Authentication method missing\");\n            }\n            for (AuthenticationProvider provider : providers.values()) {\n                try {\n                    return provider.authenticateHttpRequest(request, response);\n                } catch (Exception e) {\n                    log.debug().exception(e).log(\"Authentication failed for provider :\");\n                    // Ignore the exception because we don't know which authentication method is expected here.\n                }\n            }\n            // No authentication provided\n            if (!providers.isEmpty()) {\n                if (StringUtils.isNotBlank(anonymousUserRole)) {\n                    request.setAttribute(AuthenticatedRoleAttributeName, anonymousUserRole);\n                    request.setAttribute(AuthenticatedDataAttributeName, new AuthenticationDataHttps(request));\n                    return true;\n                }\n                // If at least a provider was configured, then the authentication needs to be provider\n                throw new AuthenticationException(\"Authentication required\");\n            } else {\n                // No authentication required\n                return true;\n            }\n        }\n    }\n\n    /**\n     * @deprecated use {@link #authenticateHttpRequest(HttpServletRequest, HttpServletResponse)}\n     */\n    @Deprecated(since = \"3.0.0\")\n    public String authenticateHttpRequest(HttpServletRequest request, AuthenticationDataSource authData)\n            throws AuthenticationException {\n        String authMethodName = getAuthMethodName(request);\n\n        if (authMethodName != null) {\n            AuthenticationProvider providerToUse = getAuthProvider(authMethodName);\n            try {","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationService.java#L145-L181","documentation":"In the servlet-based authenticateHttpRequest, when the request carries no auth method header, no provider successfully authenticated it, and no anonymousUserRole is configured, the broker rejects the request with AuthenticationException('Authentication required'). At least one provider is configured (authentication is enabled), so unauthenticated requests are not permitted.","triggerScenarios":"Request with no Pulsar-Auth-Method-Name header; every configured provider's authenticateHttpRequest fails or returns false (e.g. missing/invalid Authorization header); strictAuthMethod=false; anonymousUserRole is blank/unset.","commonSituations":"Client simply omits credentials against an auth-enabled broker; client sends credentials in a format no configured provider accepts; token expired so the token provider rejects it and no anonymous fallback exists; anonymousUserRole not set though operators expected open anonymous access.","solutions":["Send valid credentials (e.g. Authorization: Bearer <token> with Pulsar-Auth-Method-Name: token)","Set anonymousUserRole in broker.conf to allow unauthenticated requests under a fixed role","Verify the client's credential format matches one of the configured providers","Check broker logs (debug level) for which providers rejected the credentials to fix the credential itself"],"exampleFix":"// before (broker.conf): authentication enabled, no anonymous fallback\n// curl http://broker:8080/admin/v2/clusters -> Authentication required\n// after: allow anonymous or authenticate\ncurl -H \"Pulsar-Auth-Method-Name: token\" -H \"Authorization: Bearer eyJ...\" http://broker:8080/admin/v2/clusters\n// or: anonymousUserRole=anonymous","handlingStrategy":"try-catch","validationCode":"// client-side precheck: ensure credentials exist before calling\nif (authToken == null || authToken.isBlank()) {\n    throw new IllegalStateException(\"Refusing unauthenticated call to an auth-enabled broker\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    authenticated = authService.authenticateHttpRequest(request, response);\n} catch (javax.naming.AuthenticationException e) {\n    if (\"Authentication required\".equals(e.getMessage())) {\n        response.sendError(401, \"Credentials required\");\n    }\n}","preventionTips":["Always send valid credentials when the broker has authenticationEnabled=true","Set anonymousUserRole if unauthenticated access is intended","Check token expiry client-side and refresh before requests","Confirm credential format matches one of the configured providers (token/TLS/etc.)"],"tags":["authentication","pulsar","http"],"backgroundTag":"authentication-required","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}