apereo/cas · warning

Secret key for signing is not defined under

Error message

Secret key for signing is not defined under [{}]. CAS will attempt to auto-generate the signing key

What it means

Warning from BaseBinaryCipherExecutor.ensureSigningKeyExists when the configured signing secret key is blank. CAS auto-generates an octet JWK of the configured size and warns that the generated signing key must be added to settings; regenerating at each startup invalidates previously signed values.

Solutions

  1. Generate a signing JWK of the required size and set the cas.*.crypto.signing.key property.
  2. Copy the generated key from the log warning into your configuration so it survives restarts.
  3. In clustered deployments, share the same signing key property across all nodes.
  4. Disable signing if the feature does not require it instead of leaving the key blank.

Example fix

// before
cas.ticket.crypto.signing.enabled=true
// after
cas.ticket.crypto.signing.enabled=true
cas.ticket.crypto.signing.key=eyJhbGciOiJIUzUxMiJ9...generated-oct-jwk...
Defensive patterns

Strategy: validation

Validate before calling

String signingKey = casProperties.getTicket().getCrypto().getSigning().getKey();
if (signingKey == null || signingKey.isBlank()) {
    throw new IllegalStateException("Signing key missing: set cas.ticket.crypto.signing.key before startup");
}

Prevention

When it happens

Trigger: Starting CAS with signing enabled (e.g. cas.ticket.crypto.signing.key empty) for a binary cipher executor; tokens/cookies signed in a previous run cannot be verified after restart because a new random key is generated.

Common situations: First-time setup without running the keygen step; multi-node CAS deployments where each node generates a different key, breaking signed-ticket validation across nodes.

Understand the failure class

Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.

Related errors


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

Appendix: source

Thrown at core/cas-server-core-util-api/src/main/java/org/apereo/cas/util/cipher/BaseBinaryCipherExecutor.java:203

            } else if (encryptionSecretKey.length() != encryptionKeySize) {
                LOGGER.warn("Secret key for encryption defined under [{}] is Base64 encoded but the size does not match the key size [{}].",
                    getEncryptionKeySetting(), encryptionKeySize);
                genEncryptionKey = encryptionSecretKey.getBytes(StandardCharsets.UTF_8);
            } else {
                LOGGER.warn("Secret key for encryption defined under [{}] is not Base64 encoded. Clear the setting to regenerate (Recommended) or replace with"
                            + " [{}].", getEncryptionKeySetting(), EncodingUtils.encodeBase64(encryptionSecretKey));
                genEncryptionKey = encryptionSecretKey.getBytes(StandardCharsets.UTF_8);
            }
        } else {
            genEncryptionKey = EncodingUtils.decodeBase64(encryptionSecretKey);
        }
        this.encryptionSecretKey = genEncryptionKey;
    }

    private void ensureSigningKeyExists(final String signingSecretKey, final int signingKeySize) {
        var signingKeyToUse = signingSecretKey;
        if (StringUtils.isBlank(signingKeyToUse)) {
            LOGGER.warn("Secret key for signing is not defined under [{}]. CAS will attempt to auto-generate the signing key",
                getSigningKeySetting());
            signingKeyToUse = generateOctetJsonWebKeyOfSize(signingKeySize);
            val prop = String.format("%s=%s", getSigningKeySetting(), signingKeyToUse);
            issueWarningToAddKeyToSettings("signing", signingKeySize, signingKeyToUse, prop);
        }
        configureSigningKey(signingKeyToUse);
    }
    
    //CHECKSTYLE:OFF
    private static void issueWarningToAddKeyToSettings(final String keyType, final int encryptionKeySize, final String key, final String prop) {
        LOGGER.warn("Generated {} key [{}] of size [{}]. The generated key MUST be added to CAS settings:\n\n\t{}\n\n",
            keyType, key, encryptionKeySize, prop);
    }
    //CHECKSTYLE:ON
    
}

View on GitHub (pinned to e7288fc434)