apache/pulsar · error · SaslException
Cannot create JVM SASL Client
Error message
Cannot create JVM SASL Client
What it means
During construction, PulsarSaslClient asks the JVM (Sasl.createSaslClient with the GSSAPI mechanism, inside Subject.doAs) to build a SASL client for Kerberos authentication. If the JVM returns null instead of a SaslClient — meaning no provider could supply GSSAPI — this SaslException is thrown. It is distinct from 'error while booting GSSAPI client' (which wraps an actual exception); here the factory silently failed to create anything.
Source
Thrown at pulsar-client-auth-sasl/src/main/java/org/apache/pulsar/client/impl/auth/PulsarSaslClient.java:89
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());
}
});
return AuthData.of(retval);
View on GitHub (pinned to 820761864e)
Solutions
- Ensure the JVM includes the SASL/GSSAPI provider: use a full JDK or a JRE containing com.sun.security.sasl provider and confirm 'GSSAPI' support in the provider list
- Check the java.security file (JRE/lib/security/java.security) so the standard security providers (SUN, SunJGSS, SunSASL, etc.) are not removed or reordered
- Add or restore the provider programmatically if removed: Security.addProvider(new com.sun.security.sasl.Provider()) equivalent / fix security.provider.N entries
- Log/debug the SASL provider resolution (Sasl.getSaslClientFactories()) in the target container to confirm GSSAPI factories are visible to the client app
- Verify runtime matches the environment used in testing (container base image may use a slim JRE without SASL)
Example fix
// before: failing on a slim JRE without SASL provider
PulsarSaslClient client = new PulsarSaslClient(host, "broker", jaasSubject);
// after: ensure providers are present at startup
import com.sun.security.sasl.Provider;
if (java.security.Security.getProvider("SunSASL") == null) {
java.security.Security.addProvider(new Provider());
}
PulsarSaslClient client = new PulsarSaslClient(host, "broker", jaasSubject); Defensive patterns
Strategy: validation
Validate before calling
// before creating PulsarSaslClient
if (java.security.Security.getProvider("SunSASL") == null
&& java.security.Security.getProviders("SaslClientFactory.GSSAPI").length == 0) {
throw new IllegalStateException("No SASL provider with GSSAPI support on this JVM");
} Type guard
boolean gssapiAvailable() {
try {
return javax.security.sasl.Sasl.createSaslClient(
new String[]{"GSSAPI"}, null, "dummy", "dummy", null, null) != null;
} catch (Exception e) {
return false;
}
} Prevention
- Run clients on a full JDK/JRE that ships the SunSASL provider
- Never strip security.provider entries from java.security in container images
- Smoke-test Kerberos/SASL client creation at application startup, not on first message
- Pin the same JRE image across environments used in dev and prod
When it happens
Trigger: Calling new PulsarSaslClient(serverHostname, serverType, subject) when Sasl.createSaslClient(new String[]{"GSSAPI"}, ...) returns null — i.e. no installed SASL provider implements GSSAPI for the given mechanism/service/hostname combination.
Common situations: Running on a JRE (not JDK) or a stripped runtime without the com.sun.security.sasl.provider; security provider list (java.security) modified so GSSAPI-supporting providers are removed or ordered out; using a custom SASL provider setup in a container; name a JRE that lacks the SASL implementation classes.
Related errors
- error while booting GSSAPI client
- Authentication use SASL/JAAS/GSSAPI but server not have Prin
- Unrecognized SASL GSSAPI Server Callback.
- Cannot create SASL client with empty JAAS subject principal
- SASL/JAAS error${e.getCause()}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f542dfc64a83a71a.
Report an issue: GitHub.