apereo/cas · warning

Secret key for encryption defined under

Error message

Secret key for encryption defined under [{}] is not Base64 encoded. Clear the setting to regenerate (Recommended) or replace with [{}].

What it means

Warning from BaseBinaryCipherExecutor.ensureEncryptionKeyExists when the configured encryption key is neither validly sized Base64 nor missing: it is not Base64 at all (or the length branch did not match). CAS uses the raw UTF-8 bytes of the string as the AES key and suggests clearing the setting so a proper key is regenerated.

Solutions

  1. Clear the property and restart so CAS auto-generates a proper Base64 key (recommended by the message), then persist the printed key.
  2. Replace the value with the Base64 encoding of the existing secret if you must keep the same key material.
  3. Validate the value is Base64 (java.util.Base64.getDecoder().decode throws on invalid input) before configuring it.

Example fix

// before
cas.ticket.crypto.encryption.key=my-secret-password
// after
cas.ticket.crypto.encryption.key=bXktc2VjcmV0LXBhc3N3b3Jk
Defensive patterns

Strategy: validation

Validate before calling

try {
    java.util.Base64.getDecoder().decode(configuredKey);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("Encryption key is not Base64 encoded: re-generate or Base64-encode it");
}

Prevention

When it happens

Trigger: Setting cas.*.crypto.encryption.key to a plain-text string (not Base64) whose length also equals the key size — e.g. a 16-character ASCII password used directly as the encryption key.

Common situations: Operators typing a human-readable secret instead of a generated Base64 key; keys copied from another system that hex- or URL-encodes rather than Base64; whitespace or prefix corruption that invalidates Base64 decoding.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

                keyGenerator.init(encryptionKeySize);
                val secretKey = keyGenerator.generateKey();
                genEncryptionKey = secretKey.getEncoded();
                val encodedKey = EncodingUtils.encodeBase64(genEncryptionKey);
                val prop = String.format("%s=%s", getEncryptionKeySetting(), encodedKey);
                issueWarningToAddKeyToSettings("encryption", encryptionKeySize, encodedKey, prop);
            }
        } else if (encryptionKeySize <= MINIMUM_ENCRYPTION_KEY_LENGTH) {
            val base64 = EncodingUtils.isBase64(encryptionSecretKey);
            val key = base64 ? EncodingUtils.decodeBase64(encryptionSecretKey) : ArrayUtils.EMPTY_BYTE_ARRAY;
            if (base64 && key.length == encryptionKeySize) {
                LOGGER.trace("Secret key for encryption defined under [{}] is Base64 encoded.", getEncryptionKeySetting());
                genEncryptionKey = key;
            } 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);
        }

View on GitHub (pinned to e7288fc434)