{"record":{"id":"eced08fe087277e5","repo":"apache/pulsar","slug":"invalid-broker-configuration-authentication-must","errorCode":null,"errorMessage":"Invalid broker configuration. Authentication must be enabled with authenticationEnabled=true when authorization is enabled with authorizationEnabled=true.","messagePattern":"Invalid broker configuration\\. Authentication must be enabled with authenticationEnabled=true when authorization is enabled with authorizationEnabled=true\\.","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java","lineNumber":882,"sourceCode":"                .log(\"Starting Pulsar Broker service\");\n\n        long startTimestamp = System.currentTimeMillis();  // start time mills\n\n        mutex.lock();\n        try {\n            if (state != State.Init) {\n                throw new PulsarServerException(\"Cannot start the service once it was stopped\");\n            }\n\n            if (config.getWebServicePort().isEmpty()\n                    && config.getWebServicePortTls().isEmpty()\n                    && BindAddressValidator.validateBindAddresses(config, Arrays.asList(\"http\", \"https\")).isEmpty()) {\n                throw new IllegalArgumentException(\n                        \"webServicePort/webServicePortTls or http/https bindAddresses must be present\");\n            }\n\n            if (config.isAuthorizationEnabled() && !config.isAuthenticationEnabled()) {\n                throw new IllegalStateException(\"Invalid broker configuration. Authentication must be enabled with \"\n                        + \"authenticationEnabled=true when authorization is enabled with authorizationEnabled=true.\");\n            }\n\n            if (config.getDefaultRetentionSizeInMB() > 0\n                    && config.getBacklogQuotaDefaultLimitBytes() > 0\n                    && config.getBacklogQuotaDefaultLimitBytes()\n                    >= (config.getDefaultRetentionSizeInMB() * 1024L * 1024L)) {\n                throw new IllegalArgumentException(String.format(\"The retention size must > the backlog quota limit \"\n                                + \"size, but the configured backlog quota limit bytes is %d, the retention size is %d\",\n                        config.getBacklogQuotaDefaultLimitBytes(),\n                        config.getDefaultRetentionSizeInMB() * 1024L * 1024L));\n            }\n\n            if (config.getDefaultRetentionTimeInMinutes() > 0\n                    && config.getBacklogQuotaDefaultLimitSecond() > 0\n                    && config.getBacklogQuotaDefaultLimitSecond() >= config.getDefaultRetentionTimeInMinutes() * 60) {\n                throw new IllegalArgumentException(String.format(\"The retention time must > the backlog quota limit \"\n                                + \"time, but the configured backlog quota limit time duration is %d, \"","sourceCodeStart":864,"sourceCodeEnd":900,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java#L864-L900","documentation":"PulsarService.start() enforces a configuration invariant: authorization cannot be enabled without authentication, because authorization policies are only meaningful for authenticated identities. If isAuthorizationEnabled() is true but isAuthenticationEnabled() is false, startup fails fast with IllegalStateException rather than running with policies that can never be evaluated.","triggerScenarios":"Broker config where authorizationEnabled=true but authenticationEnabled=false (or the authentication provider chain is effectively not configured) when calling PulsarService.start(). The check in start(): config.isAuthorizationEnabled() && !config.isAuthenticationEnabled().","commonSituations":"Users enabling authorization for multi-tenancy but forgetting to also enable authentication; template configs with authorizationEnabled=true inherited while authentication was disabled to 'simplify' local testing; docs migration where authenticationProviderList was set but the authenticationEnabled flag was left false.","solutions":["Set authenticationEnabled=true in broker.conf and configure authenticationProviderList (e.g. org.apache.pulsar.broker.authentication.AuthenticationProviderToken) together with authorizationEnabled=true.","If you do not need authorization in a dev/test environment, set authorizationEnabled=false so the pair is consistent.","Review the full auth section of the config: also set superUserRoles / authentication parameters required by the chosen provider.","Restart with the corrected config; the check happens at start() so any change requires a broker restart to take effect."],"exampleFix":"// before (broker.conf)\nauthorizationEnabled=true\nauthenticationEnabled=false\n\n// after\nauthorizationEnabled=true\nauthenticationEnabled=true\nauthenticationProviderList=org.apache.pulsar.broker.authentication.AuthenticationProviderToken","handlingStrategy":"validation","validationCode":"if (Boolean.parseBoolean(props.getProperty(\"authorizationEnabled\", \"false\"))\n        && !Boolean.parseBoolean(props.getProperty(\"authenticationEnabled\", \"false\"))) {\n    throw new IllegalArgumentException(\n        \"authenticationEnabled=true is required when authorizationEnabled=true\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    pulsarService.start();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Authentication must be enabled\")) {\n        System.err.println(\"Fix broker.conf: set authenticationEnabled=true (plus authenticationProviderList) or disable authorization\");\n    }\n    throw e;\n}","preventionTips":["Always configure authenticationEnabled, authenticationProviderList, and authorizationEnabled as a set — never flip authorization on alone.","Add a config lint step in CI that fails when authorizationEnabled=true but authenticationEnabled!=true.","When simplifying local/dev configs, disable both flags together rather than only authentication.","Document the auth pair requirement in your deployment templates to avoid copy-paste regressions."],"tags":["configuration","authentication","authorization","security","startup"],"backgroundTag":"invalid-security-configuration","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"}