apereo/cas · warning

Token encryption/signing is not enabled explicitly in the…

Error message

Token encryption/signing is not enabled explicitly in the configuration for cookie [{}], yet signing/encryption keys are defined for operations. CAS will proceed to enable the cookie encryption/signing functionality.

What it means

When the device-fingerprint cookie's crypto signing and encryption keys are both set but crypto.enabled is false, CAS warns and force-enables cookie signing/encryption anyway. The feature works, but the configuration is ambiguous; CAS is telling you to make the intent explicit.

Solutions

  1. Explicitly set cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.enabled=true since you intend signing/encryption.
  2. If you actually want the cookie unsigned/unencrypted, remove the crypto.encryption.key and crypto.signing.key values so the warning disappears.
  3. Set the keys via secure config (env vars/secrets) and keep enabled=true in the same config source to avoid drift.

Example fix

// before
cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.enabled=false
cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.encryption.key=xyz
cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.signing.key=abc

// after
cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.enabled=true
cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.encryption.key=xyz
cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.signing.key=abc
Defensive patterns

Strategy: validation

Validate before calling

var crypto = casProperties.getAuthn().getMfa().getTrusted().getDeviceFingerprint().getCookie().getCrypto();
if (!crypto.isEnabled() && StringUtils.isNotBlank(crypto.getEncryption().getKey()) && StringUtils.isNotBlank(crypto.getSigning().getKey())) {
    throw new IllegalStateException("Set cookie crypto.enabled=true or remove the signing/encryption keys");
}

Prevention

When it happens

Trigger: In deviceFingerprintCookieCipherExecutor, crypto.isEnabled() is false while both cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.encryption.key and .signing.key are non-blank; CAS flips enabled=true and proceeds to build a CookieDeviceFingerprintComponentCipherExecutor.

Common situations: Copy-pasting crypto key config from cookie examples while forgetting cas.authn.mfa.trusted.device-fingerprint.cookie.crypto.enabled=true; keys left over from an earlier setup after toggling enabled=false; environment-variable-injected keys that make enabled=false misleading.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-trusted-mfa/src/main/java/org/apereo/cas/config/MultifactorAuthnTrustedDeviceFingerprintConfiguration.java:207

        public CookieValueManager deviceFingerprintCookieValueManager(
            @Qualifier(TenantExtractor.BEAN_NAME)
            final TenantExtractor tenantExtractor,
            @Qualifier("deviceFingerprintCookieCipherExecutor")
            final CipherExecutor deviceFingerprintCookieCipherExecutor) {
            return new EncryptedCookieValueManager(
                CipherExecutorResolver.with(deviceFingerprintCookieCipherExecutor),
                tenantExtractor, DefaultCookieSameSitePolicy.INSTANCE);
        }

        @ConditionalOnMissingBean(name = "deviceFingerprintCookieCipherExecutor")
        @Bean
        @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)
        public CipherExecutor deviceFingerprintCookieCipherExecutor(final CasConfigurationProperties casProperties) {
            val cookie = casProperties.getAuthn().getMfa().getTrusted().getDeviceFingerprint().getCookie();
            val crypto = cookie.getCrypto();
            var enabled = crypto.isEnabled();
            if (!enabled && StringUtils.isNotBlank(crypto.getEncryption().getKey()) && StringUtils.isNotBlank(crypto.getSigning().getKey())) {
                LOGGER.warn("Token encryption/signing is not enabled explicitly in the configuration for cookie [{}], yet "
                            + "signing/encryption keys are defined for operations. CAS will proceed to enable the cookie "
                            + "encryption/signing functionality.", cookie.getName());
                enabled = true;
            }
            if (enabled) {
                return CipherExecutorUtils.newStringCipherExecutor(crypto, CookieDeviceFingerprintComponentCipherExecutor.class);
            }
            return CipherExecutor.noOp();
        }

    }

    @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
    @ConditionalOnBean(name = GeoLocationService.BEAN_NAME)
    @Configuration(value = "MultifactorAuthnTrustedDeviceGeoLocationConfiguration", proxyBeanMethods = false)
    @EnableConfigurationProperties(CasConfigurationProperties.class)
    static class MultifactorAuthnTrustedDeviceGeoLocationConfiguration {
        @Bean

View on GitHub (pinned to e7288fc434)