{"record":{"id":"1bd886096930059b","repo":"apereo/cas","slug":"unable-to-encrypt-assertion-for","errorCode":null,"errorMessage":"Unable to encrypt assertion for ","messagePattern":"Unable to encrypt assertion for ","errorType":"exception","errorClass":"SamlException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/builders/enc/SamlIdPObjectEncrypter.java","lineNumber":82,"sourceCode":"\n/**\n * This is {@link SamlIdPObjectEncrypter}.\n *\n * @author Misagh Moayyed\n * @since 5.0.0\n */\n@Slf4j\n@RequiredArgsConstructor\npublic class SamlIdPObjectEncrypter {\n    private final SamlIdPProperties samlIdPProperties;\n\n    private final SamlIdPMetadataLocator samlIdPMetadataLocator;\n\n    private static void handleEncryptionFailure(final SamlRegisteredService service,\n                                                final SamlRegisteredServiceMetadataAdaptor adaptor) {\n        val entityId = adaptor.getEntityId();\n        if (!service.isEncryptionOptional()) {\n            throw new SamlException(\"Unable to encrypt assertion for \" + entityId);\n        }\n        LOGGER.debug(\"Skipping to encrypt; No encrypter can be determined and encryption is optional for [{}]\", entityId);\n    }\n\n    /**\n     * Encode a given saml object by invoking a number of outbound security handlers on the context.\n     *\n     * @param samlObject the saml object\n     * @param service    the service\n     * @param adaptor    the adaptor\n     * @return the t\n     */\n    public EncryptedAssertion encode(final Assertion samlObject,\n                                     final SamlRegisteredService service,\n                                     final SamlRegisteredServiceMetadataAdaptor adaptor) {\n\n        try {\n            val encrypter = buildEncrypterForSamlObject(samlObject, service, adaptor);","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/builders/enc/SamlIdPObjectEncrypter.java#L64-L100","documentation":"When the IdP must encrypt an assertion for an SP but no encrypter can be built (no encryption key/credential resolvable for the SP entity), handleEncryptionFailure throws SamlException unless the service marked encryption as optional. This prevents silently delivering unencrypted assertions where encryption is required.","triggerScenarios":"encode()/buildEncrypterForSamlObject fails to resolve SP encryption credentials (e.g. SP metadata lacks KeyDescriptor use=encryption, or no certificate found) and handleEncryptionFailure runs with service.isEncryptionOptional()==false.","commonSituations":"SP metadata contains only a signing certificate, not an encryption certificate; SP certificate expired/removed from metadata; encryption key size mismatch (SP can't accept the algorithm) surfaced as no usable encrypter; service misconfigured with encryption required though SP doesn't support it.","solutions":["Ensure SP metadata publishes an encryption KeyDescriptor with a usable certificate and refresh the cached metadata.","Set service.setEncryptionOptional(true) if delivering unencrypted assertions is acceptable per policy.","Configure the service's encryption parameters (algorithm, key size, fingerprint) to match what the SP supports.","Verify the correct entityID is being used to look up SP encryption credentials."],"exampleFix":"// before\nregisteredService.setEncryptionOptional(false); // SP has no encryption cert\n// after\nregisteredService.setEncryptionOptional(true); // or publish encryption cert in SP metadata","handlingStrategy":"try-catch","validationCode":"val encryptionCerts = metadataResolver.getEncryptionCertificates(entityId, service);\nif ((encryptionCerts == null || encryptionCerts.isEmpty()) && !service.isEncryptionOptional())\n    LOGGER.error(\"SP [{}] publishes no encryption certificate; encryption will fail\", entityId);","typeGuard":"boolean spSupportsEncryption(SamlRegisteredService s, String entityId) {\n    return s.isEncryptionOptional() || !getEncryptionCredentials(entityId).isEmpty();\n}","tryCatchPattern":"try {\n    val encoded = encrypter.encode(assertion, service, adaptor, ...);\n} catch (SamlException e) {\n    LOGGER.error(\"Cannot encrypt assertion for [{}]: update SP metadata or mark encryption optional\", adaptor.getEntityId());\n}","preventionTips":["Require SPs to publish an encryption KeyDescriptor in their metadata.","Set encryptionOptional only after security review.","Refresh metadata after SP certificate changes.","Validate SP metadata on registration: reject entries lacking encryption keys if encryption is mandatory."],"tags":["saml","encryption","assertion","metadata","sp"],"backgroundTag":"encryption-key-not-found","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"}