{"record":{"id":"f542dfc64a83a71a","repo":"apache/pulsar","slug":"cannot-create-jvm-sasl-client","errorCode":null,"errorMessage":"Cannot create JVM SASL Client","messagePattern":"Cannot create JVM SASL Client","errorType":"exception","errorClass":"SaslException","httpStatus":null,"severity":"error","filePath":"pulsar-client-auth-sasl/src/main/java/org/apache/pulsar/client/impl/auth/PulsarSaslClient.java","lineNumber":89,"sourceCode":"        log.info().attr(\"serverPrincipal\", serverPrincipal)\n                .log(\"Using JAAS/SASL/GSSAPI auth to connect to server\");\n\n        try {\n            this.saslClient = Subject.doAs(clientSubject, new PrivilegedExceptionAction<SaslClient>() {\n                @Override\n                public SaslClient run() throws SaslException {\n                    String[] mechs = {\"GSSAPI\"};\n                    return Sasl.createSaslClient(mechs, clientPrincipalName, serviceName, serviceHostname, null,\n                        new ClientCallbackHandler());\n                }\n            });\n        } catch (PrivilegedActionException err) {\n            log.error().exception(err.getCause()).log(\"GSSAPI client error\");\n            throw new SaslException(\"error while booting GSSAPI client\", err.getCause());\n        }\n\n        if (saslClient == null) {\n            throw new SaslException(\"Cannot create JVM SASL Client\");\n        }\n\n    }\n\n    public AuthData evaluateChallenge(final AuthData saslToken) throws AuthenticationException {\n        if (saslToken == null) {\n            throw new AuthenticationException(\"saslToken is null\");\n        }\n        try {\n            if (clientSubject != null) {\n                final byte[] retval = Subject.doAs(clientSubject, new PrivilegedExceptionAction<byte[]>() {\n                    @Override\n                    public byte[] run() throws SaslException {\n                        return saslClient.evaluateChallenge(saslToken.getBytes());\n                    }\n                });\n                return AuthData.of(retval);\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-auth-sasl/src/main/java/org/apache/pulsar/client/impl/auth/PulsarSaslClient.java#L71-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before: failing on a slim JRE without SASL provider\nPulsarSaslClient client = new PulsarSaslClient(host, \"broker\", jaasSubject);\n\n// after: ensure providers are present at startup\nimport com.sun.security.sasl.Provider;\nif (java.security.Security.getProvider(\"SunSASL\") == null) {\n    java.security.Security.addProvider(new Provider());\n}\nPulsarSaslClient client = new PulsarSaslClient(host, \"broker\", jaasSubject);","handlingStrategy":"validation","validationCode":"// before creating PulsarSaslClient\nif (java.security.Security.getProvider(\"SunSASL\") == null\n        && java.security.Security.getProviders(\"SaslClientFactory.GSSAPI\").length == 0) {\n    throw new IllegalStateException(\"No SASL provider with GSSAPI support on this JVM\");\n}","typeGuard":"boolean gssapiAvailable() {\n    try {\n        return javax.security.sasl.Sasl.createSaslClient(\n                new String[]{\"GSSAPI\"}, null, \"dummy\", \"dummy\", null, null) != null;\n    } catch (Exception e) {\n        return false;\n    }\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["sasl","kerberos","jvm","security-provider"],"backgroundTag":"sasl-client-creation-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}