{"record":{"id":"e3d4f1818b82fec3","repo":"apereo/cas","slug":"secret-key-for-signing-is-not-defined-for-ca","errorCode":null,"errorMessage":"Secret key for signing is not defined for [{}]. CAS will attempt to auto-generate the signing key","messagePattern":"Secret key for signing is not defined for \\[(.+?)\\]\\. CAS will attempt to auto-generate the signing key","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/cas-server-core-util-api/src/main/java/org/apereo/cas/util/cipher/BaseStringCipherExecutor.java","lineNumber":189,"sourceCode":"    }\n\n\n    protected String encryptValueAsJwt(final Key encryptionKey, final Serializable value) {\n        val headers = new LinkedHashMap<>(getCommonHeaders());\n        headers.putAll(getEncryptionOpHeaders());\n        return JsonWebTokenEncryptor.builder()\n            .key(encryptionKey)\n            .algorithm(encryptionAlgorithm)\n            .encryptionMethod(contentEncryptionAlgorithmIdentifier)\n            .headers(headers)\n            .build()\n            .encrypt(value);\n    }\n\n    private void configureSigningParameters(final String secretKeySigning) {\n        var signingKeyToUse = secretKeySigning;\n        if (StringUtils.isBlank(signingKeyToUse)) {\n            LOGGER.warn(\"Secret key for signing is not defined for [{}]. CAS will attempt to auto-generate the signing key\", getName());\n            signingKeyToUse = EncodingUtils.generateJsonWebKey(this.signingKeySize);\n            val prop = String.format(\"%s=%s\", getSigningKeySetting(), signingKeyToUse);\n            //CHECKSTYLE:OFF\n            LOGGER.warn(\"Generated signing key [{}] of size [{}] for [{}]. The generated key MUST be added to CAS settings:\\n\\n\\t{}\\n\\n\",\n                signingKeyToUse, this.signingKeySize, getName(), prop);\n            //CHECKSTYLE:ON\n        } else {\n            try {\n                val jwk = (PublicJsonWebKey) EncodingUtils.newJsonWebKey(signingKeyToUse);\n                LOGGER.trace(\"Parsed signing key as a JSON web key for [{}] with kid [{}]\", getName(), jwk.getKeyId());\n                if (jwk.getPrivateKey() == null) {\n                    val msg = \"Provided signing key as a JSON web key does not carry a private key\";\n                    LOGGER.error(msg);\n                    throw new RuntimeException(msg);\n                }\n                setSigningKey(jwk.getPrivateKey());\n            } catch (final Exception e) {\n                LOGGER.trace(\"Unable to recognize signing key for [{}] as a JSON web key: [{}].\", getSigningKeySetting(), e.getMessage());","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-util-api/src/main/java/org/apereo/cas/util/cipher/BaseStringCipherExecutor.java#L171-L207","documentation":"Warning from BaseStringCipherExecutor.configureSigningParameters when the signing key for a string-based cipher executor (cookies, webflow state, etc.) is blank. CAS generates a JSON Web Key of the configured signingKeySize and prints a warning containing the property to persist.","triggerScenarios":"Starting CAS with a string cipher executor enabled but its signing key property unset; the executor name appears in the message (e.g. 'CAS Cookie Encryption').","commonSituations":"Enabling encrypted/signed cookies or webflow crypto without generating keys; upgraded CAS versions where signing became mandatory and legacy configs lack the key; cluster nodes drifting apart with per-node generated keys.","solutions":["Generate a signing JWK and set the property named in getSigningKeySetting() (printed in the follow-up warning line).","Persist the key so restarts do not regenerate it and invalidate signed values.","Use the same signing key on every CAS node in the deployment.","If signing is unnecessary, disable it explicitly rather than leaving the key blank."],"exampleFix":"// before\ncas.webflow.crypto.signing.enabled=true\n// after\ncas.webflow.crypto.signing.enabled=true\ncas.webflow.crypto.signing.key=eyJvY3R...generated-jwk...","handlingStrategy":"validation","validationCode":"String signingKey = webflowCrypto.getSigning().getKey();\nif (signingKey == null || signingKey.isBlank()) {\n    throw new IllegalStateException(\"Webflow signing key not configured; generate and persist a JWK\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair every signing.enabled=true flag with a generated, persisted signing key.","Check for this warning after CAS upgrades that tighten crypto defaults.","Use one shared JWK across all nodes."],"tags":["signing","jwk","missing-config"],"backgroundTag":"missing-config-value","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}