apache/pulsar · error · IllegalStateException
Invalid broker configuration. Authentication must be enabled
Error message
Invalid broker configuration. Authentication must be enabled with authenticationEnabled=true when authorization is enabled with authorizationEnabled=true.
What it means
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.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java:882
.log("Starting Pulsar Broker service");
long startTimestamp = System.currentTimeMillis(); // start time mills
mutex.lock();
try {
if (state != State.Init) {
throw new PulsarServerException("Cannot start the service once it was stopped");
}
if (config.getWebServicePort().isEmpty()
&& config.getWebServicePortTls().isEmpty()
&& BindAddressValidator.validateBindAddresses(config, Arrays.asList("http", "https")).isEmpty()) {
throw new IllegalArgumentException(
"webServicePort/webServicePortTls or http/https bindAddresses must be present");
}
if (config.isAuthorizationEnabled() && !config.isAuthenticationEnabled()) {
throw new IllegalStateException("Invalid broker configuration. Authentication must be enabled with "
+ "authenticationEnabled=true when authorization is enabled with authorizationEnabled=true.");
}
if (config.getDefaultRetentionSizeInMB() > 0
&& config.getBacklogQuotaDefaultLimitBytes() > 0
&& config.getBacklogQuotaDefaultLimitBytes()
>= (config.getDefaultRetentionSizeInMB() * 1024L * 1024L)) {
throw new IllegalArgumentException(String.format("The retention size must > the backlog quota limit "
+ "size, but the configured backlog quota limit bytes is %d, the retention size is %d",
config.getBacklogQuotaDefaultLimitBytes(),
config.getDefaultRetentionSizeInMB() * 1024L * 1024L));
}
if (config.getDefaultRetentionTimeInMinutes() > 0
&& config.getBacklogQuotaDefaultLimitSecond() > 0
&& config.getBacklogQuotaDefaultLimitSecond() >= config.getDefaultRetentionTimeInMinutes() * 60) {
throw new IllegalArgumentException(String.format("The retention time must > the backlog quota limit "
+ "time, but the configured backlog quota limit time duration is %d, "View on GitHub (pinned to 820761864e)
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.
Example fix
// before (broker.conf) authorizationEnabled=true authenticationEnabled=false // after authorizationEnabled=true authenticationEnabled=true authenticationProviderList=org.apache.pulsar.broker.authentication.AuthenticationProviderToken
Defensive patterns
Strategy: validation
Validate before calling
if (Boolean.parseBoolean(props.getProperty("authorizationEnabled", "false"))
&& !Boolean.parseBoolean(props.getProperty("authenticationEnabled", "false"))) {
throw new IllegalArgumentException(
"authenticationEnabled=true is required when authorizationEnabled=true");
} Try / catch
try {
pulsarService.start();
} catch (IllegalStateException e) {
if (e.getMessage().contains("Authentication must be enabled")) {
System.err.println("Fix broker.conf: set authenticationEnabled=true (plus authenticationProviderList) or disable authorization");
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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().
Common situations: 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.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid proxy configuration. Authentication must be enabled
- No athenz domain name specified
- No secret key was provided for token authentication
- invalid algorithm provided ${tokenPublicAlg}
- Failed to initialize authorization manager due to empty Conf
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/eced08fe087277e5.
Report an issue: GitHub.