nathanmarz/storm · critical · IOException

Could not find a ' ' entry in this configuration: Server…

Error message

Could not find a '${AuthUtils.LOGIN_CONTEXT_SERVER}' entry in this configuration: Server cannot start.

What it means

ServerCallbackHandler implements the SASL server-side callbacks for Storm's DIGEST-MD5 digest authentication. It reads the JAAS configuration section named AuthUtils.LOGIN_CONTEXT_SERVER ("Server") and populates a user->password map from its options. When configuration.getAppConfigurationEntry(AuthUtils.LOGIN_CONTEXT_SERVER) returns null (no 'Server' section exists), it throws this IOException because the server cannot authenticate any client without its credential table.

Solutions

  1. Add a 'Server { ... }' section to the JAAS file with user-prefixed credentials, e.g. Server { org.apache.storm.security.auth.digest.MD5DigestLoginModule required user_admin="secret"; };
  2. Confirm the section is exactly named 'Server' (case-sensitive match against AuthUtils.LOGIN_CONTEXT_SERVER).
  3. Ensure every node running Nimbus/supervisor/ui loads the correct JAAS file via -Djava.security.auth.login.config in the master childopts.
  4. If digest auth is undesired, revert storm.thrift.transport to a non-SASL transport (e.g. SimpleTransportPlugin).

Example fix

// jaas.conf before (client only)
Client { com.myauth.MD5DigestLoginModule required username="admin" password="secret"; };
// after
Client { com.myauth.MD5DigestLoginModule required username="admin" password="secret"; };
Server { com.myauth.MD5DigestLoginModule required user_admin="secret"; };
Defensive patterns

Strategy: validation

Validate before calling

Configuration jaas = Configuration.getConfiguration();
if (jaas == null || jaas.getAppConfigurationEntry("Server") == null) {
    throw new IllegalStateException("JAAS config is missing the required 'Server' section");
}

Try / catch

try {
    Configuration c = Configuration.getConfiguration();
    if (c.getAppConfigurationEntry("Server") == null) {
        throw new IllegalStateException("Server JAAS section missing before starting Nimbus/supervisor");
    }
} catch (IOException e) {
    throw new IllegalStateException("Failed to validate JAAS config: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Constructing ServerCallbackHandler with a Configuration that contains no JAAS entry named 'Server' — e.g. the JAAS file loaded via -Djava.security.auth.login.config only defines a 'Client' section, or the server section is named differently (like 'StormServer') than AuthUtils.LOGIN_CONTEXT_SERVER.

Common situations: Nimbus/supervisor/ui startup with DigestMd5ClientTransportPlugin configured but jaas.conf missing the 'Server' block; reusing a zookeeper/kafka jaas.conf that lacks a Storm 'Server' section; section renamed during config migration; wrong file supplied on the master nodes.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12). Data as JSON: /api/errors/00cc50bea4cab094. Report an issue: GitHub.

Appendix: source

Thrown at storm-core/src/jvm/backtype/storm/security/auth/digest/ServerCallbackHandler.java:54

/**
 * SASL server side collback handler
 */
public class ServerCallbackHandler implements CallbackHandler {
    private static final String USER_PREFIX = "user_";
    private static final Logger LOG = LoggerFactory.getLogger(ServerCallbackHandler.class);
    private static final String SYSPROP_SUPER_PASSWORD = "storm.SASLAuthenticationProvider.superPassword";

    private String userName;
    private final Map<String,String> credentials = new HashMap<String,String>();

    public ServerCallbackHandler(Configuration configuration) throws IOException {
        if (configuration==null) return;

        AppConfigurationEntry configurationEntries[] = configuration.getAppConfigurationEntry(AuthUtils.LOGIN_CONTEXT_SERVER);
        if (configurationEntries == null) {
            String errorMessage = "Could not find a '"+AuthUtils.LOGIN_CONTEXT_SERVER+"' entry in this configuration: Server cannot start.";
            throw new IOException(errorMessage);
        }
        credentials.clear();
        for(AppConfigurationEntry entry: configurationEntries) {
            Map<String,?> options = entry.getOptions();
            // Populate DIGEST-MD5 user -> password map with JAAS configuration entries from the "Server" section.
            // Usernames are distinguished from other options by prefixing the username with a "user_" prefix.
            for(Map.Entry<String, ?> pair : options.entrySet()) {
                String key = pair.getKey();
                if (key.startsWith(USER_PREFIX)) {
                    String userName = key.substring(USER_PREFIX.length());
                    credentials.put(userName,(String)pair.getValue());
                }
            }
        }
    }

    public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
        for (Callback callback : callbacks) {

View on GitHub (pinned to cdb116e942)