apereo/cas · warning
Secret key for encryption defined under
Error message
Secret key for encryption defined under [{}] is Base64 encoded but the size does not match the key size [{}]. What it means
Warning from BaseBinaryCipherExecutor.ensureEncryptionKeyExists when the configured encryption key IS Base64 encoded but its decoded byte length does not equal the required encryptionKeySize (e.g. 16/24/32 bytes for AES). CAS falls back to using the raw UTF-8 bytes of the configured string as the key, which may not match the expected algorithm key size.
Solutions
- Regenerate a Base64 key of the exact size required (decoded bytes == encryptionKeySize) and replace the configured value.
- Verify with a quick decode: Base64.getDecoder().decode(key).length must equal the configured key size.
- Align the encryption.key-size setting with the key you intend to keep, if the longer/shorter key is intentional.
- Decode the key yourself and check length before setting it, e.g. with openssl rand -base64 16 for 128-bit.
Example fix
// before cas.ticket.crypto.encryption.key=ZXh0cmFsb25na2V5dGhhdGRvZXNub3RtYXRjaA== // after: key whose decoded length is exactly 16 bytes for 128-bit cas.ticket.crypto.encryption.key=MTIzNDU2Nzg5MGFiY2RlZg==
Defensive patterns
Strategy: validation
Validate before calling
byte[] decoded = java.util.Base64.getDecoder().decode(configuredKey);
int required = casProperties.getTicket().getCrypto().getEncryption().getKeySize();
if (decoded.length != required / 8) {
throw new IllegalStateException("Key decodes to " + decoded.length + " bytes; expected " + required / 8);
} Prevention
- Generate keys with the same tool and size settings you configure at runtime.
- Never hand-truncate or edit generated keys.
- Re-run keygen whenever you change cas.*.crypto.encryption.key-size.
- Document key size in bytes vs bits to avoid confusion.
When it happens
Trigger: Setting a Base64-encoded encryption key whose decoded length differs from the configured key size — e.g. a 128-bit AES cipher executor given a key that decodes to 20 bytes, or key-size settings changed after the key was generated.
Common situations: Copying a truncated key into properties; mixing a key generated for 256-bit signing with a 128-bit encryption setting; changing cas.*.crypto.encryption.key-size after deployment without regenerating keys.
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
- Secret key for encryption defined under
- Unable to use 'none' as introspection encryption algorithm
- Unable to use 'none' as user-info encryption algorithm
- Service with client id is configured to encrypt tokens, yet…
- Unable to use 'none' as ID token encryption algorithm
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/aec305ebb0709026.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-util-api/src/main/java/org/apereo/cas/util/cipher/BaseBinaryCipherExecutor.java:186
issueWarningToAddKeyToSettings("encryption", encryptionKeySize, key, prop);
genEncryptionKey = EncodingUtils.decodeBase64(key);
} else {
val keyGenerator = FunctionUtils.doUnchecked(() -> KeyGenerator.getInstance(this.secretKeyAlgorithm));
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());View on GitHub (pinned to e7288fc434)