apache/pulsar · critical · LoginException

loginContext name (JAAS file section header) was null. Pleas

Error message

loginContext name (JAAS file section header) was null. Please check your java.security.login.auth.config (=java.security.login.auth.config) for section header: loginContextName

What it means

JAASCredentialsContainer's constructor performs a JAAS LoginContext login. When Configuration.getApplicationConfiguration returns null for the configured loginContextName, there is no matching section header in the JAAS config file, so it logs the error and throws LoginException. The library cannot authenticate without a JAAS entry.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/sasl/JAASCredentialsContainer.java:67

    private LoginContext loginContext;
    private Map<String, String> configuration;

    public JAASCredentialsContainer(String loginContextName,
                                    CallbackHandler callbackHandler,
                                    Map<String, String> configuration)
        throws LoginException {
        this.configuration = configuration;
        this.callbackHandler = callbackHandler;
        this.loginContextName = loginContextName;
        AppConfigurationEntry[] entries = Configuration.getConfiguration()
            .getAppConfigurationEntry(loginContextName);
        if (entries == null) {
            final String errorMessage = "loginContext name (JAAS file section header) was null. "
                + "Please check your java.security.login.auth.config (="
                + System.getProperty("java.security.login.auth.config")
                + ") for section header: " + this.loginContextName;
            log.error().attr("details", errorMessage).log("No JAAS Configuration section header found for Client");
            throw new LoginException(errorMessage);
        }
        LoginContext loginContext = new LoginContext(loginContextName, callbackHandler);
        loginContext.login();
        log.info("successfully logged in.");

        this.loginContext = loginContext;
        this.subject = loginContext.getSubject();
        this.isKrbTicket = !this.subject.getPrivateCredentials(KerberosTicket.class).isEmpty();
        if (isKrbTicket) {
            this.isUsingTicketCache = SaslConstants.isUsingTicketCache(loginContextName);
            this.principal = SaslConstants.getPrincipal(loginContextName);
            this.ticketRefreshThread = new TGTRefreshThread(this);
        } else {
            throw new LoginException("Kerberos authentication without KerberosTicket provided!");
        }

        ticketRefreshThread.start();
    }

View on GitHub (pinned to 820761864e)

Solutions

  1. Set -Djava.security.auth.login.config=/path/to/jaas.conf (the standard property) pointing at an existing JAAS file
  2. Add a section named exactly as loginContextName, e.g. 'PulsarClient { com.sun.security.auth.module.Krb5LoginModule required ...; };'
  3. Verify the JAAS file is readable by the process and mounted in containers
  4. Confirm the section header spelling matches the configured loginContextName

Example fix

// before
// no JAAS config supplied -> LoginException
// after (jaas.conf)
PulsarClient {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true keyTab="/etc/security/pulsar.keytab"
  principal="pulsar/host@REALM";
};
// launch with: -Djava.security.auth.login.config=/etc/pulsar/jaas.conf
Defensive patterns

Strategy: validation

Validate before calling

// Verify JAAS config is resolvable before constructing credentials
String config = System.getProperty("java.security.auth.login.config");
if (config == null || !new java.io.File(config).canRead()) {
    throw new IllegalStateException("JAAS config file missing/unreadable: " + config);
}
javax.security.auth.login.Configuration cfg =
    javax.security.auth.login.Configuration.getConfiguration();
if (cfg.getAppConfigurationEntry("PulsarClient") == null) {
    throw new IllegalStateException("JAAS section 'PulsarClient' not found in " + config);
}

Type guard

static boolean jaasSectionExists(String loginContextName) {
    try {
        return javax.security.auth.login.Configuration.getConfiguration()
            .getAppConfigurationEntry(loginContextName) != null;
    } catch (Exception e) { return false; }
}

Try / catch

try {
    container = new JAASCredentialsContainer(subject, handler, "PulsarClient", serviceName);
} catch (LoginException e) {
    log.error("JAAS login failed — check -Djava.security.auth.login.config and section name: {}", e.getMessage());
    throw new AuthenticationException("Kerberos/JAAS configuration invalid", e);
}

Prevention

When it happens

Trigger: Constructing JAASCredentialsContainer with a loginContextName (e.g. 'KafkaClient', 'PulsarClient') that has no corresponding section in the file pointed to by java.security.login.auth.config, or when that system property/file is missing entirely.

Common situations: Kerberos SASL setup where -Djava.security.auth.login.config points to a missing/typo'd JAAS file; JAAS file lacks the expected section name; property name confusion (the message references java.security.login.auth.config); deploying without the keytab/JAAS sidecar file.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/a23d5f42acf1284c. Report an issue: GitHub.