apache/pulsar · error · SaslException
error while booting GSSAPI client
Error message
error while booting GSSAPI client
What it means
PulsarSaslClient creates the JVM SASL client (GSSAPI mechanism) inside Subject.doAs(...) via Sasl.createSaslClient; if that privileged action throws (PrivilegedActionException), the cause is wrapped in a SaslException with this message. It indicates the underlying SASL/GSSAPI/JNDI-Kerberos layer failed to instantiate the client mechanism — usually a Kerberos infrastructure problem (missing krb5.conf, bad principal/realm, no native GSS-API or JGSS failure), not a code bug.
Source
Thrown at pulsar-client-auth-sasl/src/main/java/org/apache/pulsar/client/impl/auth/PulsarSaslClient.java:85
KerberosName serviceKerberosName = new KerberosName(serverPrincipal + "@" + clientKerberosName.getRealm());
final String serviceName = serviceKerberosName.getServiceName();
final String serviceHostname = serviceKerberosName.getHostName();
final String clientPrincipalName = clientKerberosName.toString();
log.info().attr("serverPrincipal", serverPrincipal)
.log("Using JAAS/SASL/GSSAPI auth to connect to server");
try {
this.saslClient = Subject.doAs(clientSubject, new PrivilegedExceptionAction<SaslClient>() {
@Override
public SaslClient run() throws SaslException {
String[] mechs = {"GSSAPI"};
return Sasl.createSaslClient(mechs, clientPrincipalName, serviceName, serviceHostname, null,
new ClientCallbackHandler());
}
});
} catch (PrivilegedActionException err) {
log.error().exception(err.getCause()).log("GSSAPI client error");
throw new SaslException("error while booting GSSAPI client", err.getCause());
}
if (saslClient == null) {
throw new SaslException("Cannot create JVM SASL Client");
}
}
public AuthData evaluateChallenge(final AuthData saslToken) throws AuthenticationException {
if (saslToken == null) {
throw new AuthenticationException("saslToken is null");
}
try {
if (clientSubject != null) {
final byte[] retval = Subject.doAs(clientSubject, new PrivilegedExceptionAction<byte[]>() {
@Override
public byte[] run() throws SaslException {
return saslClient.evaluateChallenge(saslToken.getBytes());View on GitHub (pinned to 820761864e)
Solutions
- Inspect the wrapped cause (err.getCause()) in logs — the 'GSSAPI client error' log line names the underlying GSSException.
- Ensure krb5.conf is present and valid (set -Djava.security.krb5.conf=/etc/krb5.conf) and the realm/KDC are reachable.
- Confirm a valid TGT exists (klist) and the JAAS subject's principal matches the keytab/kdc principal, including realm casing.
- Run with -Dsun.security.jgss.debug=true and -Dsun.security.spnego.debug=true to diagnose; verify the JVM includes the GSSAPI SASL provider (full JDK, not stripped JRE).
Example fix
// before
java -jar client.jar // GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
// after
java -Djava.security.krb5.conf=/etc/krb5.conf \
-Dsun.security.jgss.debug=true \
-Djava.security.auth.login.config=/etc/pulsar/jaas.conf \
-jar client.jar // after kinit -kt client.keytab user@REALM Defensive patterns
Strategy: try-catch
Validate before calling
// Java: pre-flight Kerberos environment checks
static void validateKerberosEnv() {
String krb5 = System.getProperty("java.security.krb5.conf", "/etc/krb5.conf");
if (!new File(krb5).canRead()) throw new IllegalStateException("krb5.conf missing: " + krb5);
// probe that JGSS is functional:
try {
org.ietf.jgss.GSSManager factory = org.ietf.jgss.GSSManager.getInstance();
factory.createName("user@REALM", org.ietf.jgss.GSSName.NT_USER_NAME);
} catch (org.ietf.jgss.GSSException e) {
throw new IllegalStateException("GSS init failed: " + e.getMessage(), e);
}
}
// also verify a TGT: klist or Subject.getSubject(AccessController.getContext())
// has a KerberosTicket for krbtgt/REALM Try / catch
try {
PulsarSaslClient client = new PulsarSaslClient(host, serverType, subject);
} catch (SaslException e) {
if (e.getMessage().contains("error while booting GSSAPI client")) {
// e.getCause() is the GSSException/SaslException from createSaslClient
log.error("GSSAPI init failed: {} — check krb5.conf, KDC reachability and TGT", e.getCause());
// optionally re-kinit and retry once
} else { throw e; }
} Prevention
- kinit (or keytab login) before startup and refresh tickets (relogin) for long-running processes.
- Ship a valid krb5.conf and set -Djava.security.krb5.conf; verify KDC reachability from the client host.
- Use a full JDK — minimal/stripped JVMs may lack the GSSAPI SASL provider.
- Enable -Dsun.security.jgss.debug=true in staging to catch GSS issues early.
When it happens
Trigger: Sasl.createSaslClient({"GSSAPI"}, ...) throwing inside the privileged action — e.g. no default realm/krb5.conf found, client principal name unparseable, GSSException from JGSS initialization, or SASL provider missing GSSAPI support (atypical JVM).
Common situations: Missing or invalid /etc/krb5.conf (or -Djava.security.krb5.conf unset) so realm discovery fails; client principal's realm not resolvable; JDK without unrestricted JGSS/crypto policies; running in a minimal JRE lacking the SASL GSSAPI provider.
Related errors
- Cannot create JVM SASL Client
- loginContext name (JAAS file section header) was null. Pleas
- Malformed Kerberos name: name
- Invalid rule: remaining
- Authentication use SASL/JAAS/GSSAPI but server not have Prin
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/87c068f885dadf19.
Report an issue: GitHub.