apereo/cas · warning

Keystore file, password or alias assigned to the realm are…

Error message

Keystore file, password or alias assigned to the realm are undefined

What it means

CoreWsSecuritySecurityTokenServiceConfiguration.casRealm builds a RealmProperties for the STS. If keystoreFile, keystorePassword, keyPassword, or keystoreAlias is blank for the realm configuration it logs this warning and skips assigning signature crypto properties and the callback handler, leaving the realm without signing capability.

Solutions

  1. Set all four properties: keystoreFile, keystorePassword, keyPassword, keystoreAlias for each configured realm.
  2. Verify the keystore file exists at the configured path and is readable by the CAS process.
  3. Check env var/secret injection isn't producing empty strings for these values.
  4. After fixing, confirm the realm logs signature crypto setup instead of the warning.

Example fix

// before
cas.authn.ws-sts.realm[0].keystore-file=
// after
cas.authn.ws-sts.realm[0].keystore-file=/etc/cas/sts-keystore.jks
cas.authn.ws-sts.realm[0].keystore-password=changeit
cas.authn.ws-sts.realm[0].key-password=changeit
cas.authn.ws-sts.realm[0].keystore-alias=sts
Defensive patterns

Strategy: validation

Validate before calling

var rc = casProperties.getAuthn().getWsSts().getRealm();
if (StringUtils.isBlank(rc.getKeystoreFile()) || StringUtils.isBlank(rc.getKeystorePassword())
    || StringUtils.isBlank(rc.getKeyPassword()) || StringUtils.isBlank(rc.getKeystoreAlias())) {
    throw new IllegalStateException("WS-STS realm keystore settings incomplete");
}
if (!new File(rc.getKeystoreFile()).canRead()) {
    throw new IllegalStateException("Keystore not readable: " + rc.getKeystoreFile());
}

Prevention

When it happens

Trigger: cas.authn.ws-sts.realm.* configuration lacks any of keystore-file, keystore-password, key-password, or keystore-alias.

Common situations: Keystore path typo or file not mounted in container; secrets injected as empty env vars; only partial realm config copied from another environment; alias wrong so developer removed it.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/5e282627a765e646. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-ws-sts/src/main/java/org/apereo/cas/config/CoreWsSecuritySecurityTokenServiceConfiguration.java:239

                casProperties.getServer().getPrefix(), hostnameVerifier, casSslContext);
        }
    }

    @Configuration(value = "CoreWsSecuritySecurityTokenServiceRealmsConfiguration", proxyBeanMethods = false)
    @EnableConfigurationProperties(CasConfigurationProperties.class)
    static class CoreWsSecuritySecurityTokenServiceRealmsConfiguration {
        @ConditionalOnMissingBean(name = "casRealm")
        @Bean
        public RealmProperties casRealm(final CasConfigurationProperties casProperties) {
            val wsfed = casProperties.getAuthn().getWsfedIdp().getSts();
            val realmConfig = wsfed.getRealm();
            val realm = new RealmProperties();
            realm.setIssuer(StringUtils.defaultIfBlank(realmConfig.getIssuer(), casProperties.getServer().getPrefix()));
            if (StringUtils.isBlank(realmConfig.getKeystoreFile())
                || StringUtils.isBlank(realmConfig.getKeystorePassword())
                || StringUtils.isBlank(realmConfig.getKeyPassword())
                || StringUtils.isBlank(realmConfig.getKeystoreAlias())) {
                LOGGER.warn("Keystore file, password or alias assigned to the realm are undefined");
            } else {
                val properties = CryptoUtils.getSecurityProperties(realmConfig.getKeystoreFile(), realmConfig.getKeystorePassword(), realmConfig.getKeystoreAlias());
                realm.setSignatureCryptoProperties(properties);
                realm.setCallbackHandler(new RealmPasswordVerificationCallbackHandler(realmConfig.getKeyPassword().toCharArray()));
            }
            return realm;
        }

        @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
        @Bean
        @ConditionalOnMissingBean(name = "securityTokenServiceRealms")
        public Map<String, RealmProperties> securityTokenServiceRealms(
            final CasConfigurationProperties casProperties,
            @Qualifier("casRealm") final RealmProperties casRealm) {
            val idp = casProperties.getAuthn().getWsfedIdp().getIdp();
            val realms = new HashMap<String, RealmProperties>();
            realms.put(idp.getRealmName(), casRealm);
            return realms;

View on GitHub (pinned to e7288fc434)