apache/pulsar · critical · SaslException
Authentication use SASL/JAAS/GSSAPI but server not have Prin
Error message
Authentication use SASL/JAAS/GSSAPI but server not have Principals
What it means
Thrown as a javax.security.sasl.SaslException when the broker's SASL/GSSAPI (Kerberos) server is constructed but the JAAS Subject supplied to PulsarSaslServer contains no Principals. The GSSAPI mechanism requires the server to hold a Kerberos service principal (e.g. broker/myhost@REALM) loaded via a JAAS login (Krb5LoginModule); without it, SASL cannot be bootstrapped, so createSaslServer fails fast.
Source
Thrown at pulsar-broker-auth-sasl/src/main/java/org/apache/pulsar/broker/authentication/PulsarSaslServer.java:119
saslServer = Sasl.createSaslServer(GSSAPI, servicePrincipalName, serviceHostname,
null, callbackHandler);
return saslServer;
} catch (SaslException e) {
throw new RuntimeException(e);
}
}
}
);
} catch (PrivilegedActionException e) {
throw new SaslException("error on GSSAPI boot", e.getCause());
}
} catch (IndexOutOfBoundsException e) {
throw new SaslException("error on GSSAPI boot", e);
}
} else {
String errorMessage = "Authentication use SASL/JAAS/GSSAPI but server not have Principals";
log.error(errorMessage);
throw new SaslException(errorMessage);
}
}
public boolean isComplete() {
return saslServer.isComplete();
}
/**
* Reports the authorization ID in effect for the client of this
* session.
* This method can only be called if isComplete() returns true.
* @return The authorization ID of the client.
* @exception IllegalStateException if this authentication session has not completed
*/
public String getAuthorizationID() throws IllegalStateException {
return saslServer.getAuthorizationID();
}
View on GitHub (pinned to 820761864e)
Solutions
- Set -Djava.security.auth.login.config=/path/to/broker_jaas.conf with a valid Kerberos entry (useKeyTab=true keyTab=... principal='broker/_HOST@REALM') and restart the broker
- Verify the principal and keytab: run klist -k on the keytab and confirm the principal exists in the KDC; fix useKeyTab/keyTab/principal values in jaas.conf
- Confirm the JAAS login actually succeeded at startup (check broker logs for LoginException during AuthenticationProviderSasl initialization); fix KDC connectivity (DNS, /etc/krb5.conf)
- If running without Kerberos intentionally, switch the authentication provider instead of using SASL/GSSAPI
Example fix
// before (broker_env)
# PULSAR_EXTRA_OPTS left without JAAS config
// after
PULSAR_EXTRA_OPTS="${PULSAR_EXTRA_OPTS} -Djava.security.auth.login.config=/etc/pulsar/broker_jaas.conf"
# broker_jaas.conf
PulsarBroker {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true keyTab="/etc/security/keytabs/broker.keytab"
principal="broker/myhost.foo.com@EXAMPLE.COM" storeKey=true;
}; Defensive patterns
Strategy: validation
Validate before calling
// before constructing PulsarSaslServer
Subject serverSubject = loginContext.getSubject();
if (serverSubject == null || serverSubject.getPrincipals().isEmpty()) {
throw new IOException("No principals in server subject: check java.security.auth.login.config and the JAAS keytab entry");
} Try / catch
try {
PulsarSaslServer server = new PulsarSaslServer(subject, allowedIdsPattern);
} catch (SaslException e) {
if (e.getMessage().contains("server not have Principals")) {
// fail broker startup with a config-guidance message
throw new IllegalStateException("Kerberos JAAS login produced no principals; verify -Djava.security.auth.login.config, keytab path and principal", e);
}
throw e;
} Prevention
- Always set -Djava.security.auth.login.config to a JAAS file with a valid Krb5LoginModule keytab entry before enabling SASL auth
- Verify the keytab with klist -kt and test with kinit -kt before broker startup
- Check broker startup logs for LoginException from the JAAS login; treat an empty Subject as fatal
- Validate the principal name format (service/hostname@REALM) matches the keytab entry
When it happens
Trigger: Constructing PulsarSaslServer (new PulsarSaslServer(subject, allowedIdsPattern)) when subject.getPrincipals().size() == 0 — i.e. the Subject was created empty or the JAAS login that should populate it never ran or failed silently.
Common situations: Broker started with sasl authentication enabled but missing/mislocated jaas.conf (java.security.auth.login.config not set or wrong path); JAAS config file lacks the expected login context (e.g. PulsarBroker entry) or uses a non-Kerberos LoginModule; keytab path or principal name in jaas.conf is wrong so login produced an empty Subject; KDC unreachable causing a failed login treated as empty subject.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unrecognized SASL GSSAPI Server Callback.
- Cannot create SASL client with empty JAAS subject principal
- SASL/JAAS error${e.getCause()}
- Kerberos authentication without KerberosTicket provided!
- Invalid token string, missing attributes
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/21122aacff794b80.
Report an issue: GitHub.