{"record":{"id":"c4e80bd422b902e7","repo":"apereo/cas","slug":"unable-to-resolve-the-encryption-public-key-for-c4e80b","errorCode":null,"errorMessage":"Unable to resolve the encryption [public] key for entity id [{}]","messagePattern":"Unable to resolve the encryption \\[public\\] key for entity id \\[(.+?)\\]","errorType":"console","errorClass":null,"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":328,"sourceCode":"        val roleDescriptorResolver = SamlIdPUtils.getRoleDescriptorResolver(adaptor,\n            samlIdPProperties.getMetadata().getCore().isRequireValidMetadata());\n\n        mdCredentialResolver.setRoleDescriptorResolver(roleDescriptorResolver);\n        mdCredentialResolver.initialize();\n\n        val criteriaSet = new CriteriaSet();\n        criteriaSet.add(new EncryptionConfigurationCriterion(encryptionConfiguration));\n        criteriaSet.add(new EntityIdCriterion(peerEntityId));\n        criteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));\n        criteriaSet.add(new UsageCriterion(UsageType.ENCRYPTION));\n        criteriaSet.add(new SamlIdPSamlRegisteredServiceCriterion(service));\n\n        LOGGER.debug(\"Attempting to resolve the encryption key for entity id [{}]\", peerEntityId);\n        val credential = mdCredentialResolver.resolveSingle(criteriaSet);\n\n        if (credential == null || credential.getPublicKey() == null) {\n            if (service.isEncryptionOptional()) {\n                LOGGER.warn(\"Unable to resolve the encryption [public] key for entity id [{}]\", peerEntityId);\n                return null;\n            }\n            throw new SamlException(\"Unable to resolve the encryption [public] key for entity id \" + peerEntityId);\n        }\n\n        val encodedKey = EncodingUtils.encodeBase64(credential.getPublicKey().getEncoded());\n        LOGGER.debug(\"Found encryption public key: [{}]\", encodedKey);\n        encryptionConfiguration.setKeyTransportEncryptionCredentials(CollectionUtils.wrapList(credential));\n        return credential;\n    }\n\n    /**\n     * Resolve encryption parameters.\n     *\n     * @param service                 the service\n     * @param encryptionConfiguration the encryption configuration\n     * @return the encryption parameters\n     * @throws ResolverException the exception","sourceCodeStart":310,"sourceCodeEnd":346,"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#L310-L346","documentation":"The SAML IdP encrypter could not obtain an encryption (X.509 public key) credential for the peer SP from its metadata while building an OpenSAML Encrypter. When the registered service marks encryption as optional, the IdP logs a warning and proceeds without encryption; otherwise it throws SamlException and the response fails.","triggerScenarios":"buildEncrypterForSamlObject -> configureKeyEncryptionCredential runs mdCredentialResolver.resolveSingle(criteriaSet) for the peer entity ID and the metadata contains no KeyDescriptor with encryption use (or no valid public key) for that SP.","commonSituations":"SP metadata lacks USAGE_TYPE_ENCRYPTION KeyDescriptors; SP metadata loaded is the wrong entity or expired; mdCredentialResolver criteria (entity ID, roles, validUntil) do not match; service is configured with encryption required but the SP never published an encryption cert.","solutions":["Verify the SP metadata contains a KeyDescriptor of type encryption with a valid X.509 certificate for the exact entity ID being resolved","Mark the service as encryption-optional (service.isEncryptionOptional() = true) if unencrypted assertions are acceptable","Re-fetch/reload current SP metadata (check entity ID, entityID attribute, and metadata validity interval)","Confirm the mdCredentialResolver criteria set (entity ID, SPSSODescriptor role) matches how the metadata was indexed"],"exampleFix":"// before (JSON/YAML service config)\n\"encryptionOptional\": false\n// after\n\"encryptionOptional\": true","handlingStrategy":"validation","validationCode":"// Before building the encrypter, verify the SP metadata exposes an encryption key\nval criteria = new CriteriaSet(\n    new EntityIdCriterion(peerEntityId),\n    new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));\nval cred = mdCredentialResolver.resolveSingle(criteria);\nif (cred == null || cred.getPublicKey() == null) {\n    // inspect service metadata or set encryptionOptional before proceeding\n}","typeGuard":null,"tryCatchPattern":"try {\n    encrypter = buildEncrypterForSamlObject(...);\n} catch (SamlException e) {\n    // key unresolved for peer entity: fall back to unsigned/unencrypted or fail request\n    LOGGER.error(\"No encryption key for entity [{}]\", peerEntityId, e);\n}","preventionTips":["Ensure SP metadata includes KeyDescriptor use=encryption with a valid certificate","Keep SP metadata refreshed and within its validUntil window","Set encryptionOptional only when the SP accepts plaintext assertions","Log and audit resolved credentials for each SP at startup"],"tags":["saml","saml-idp","encryption","metadata","x509"],"backgroundTag":"missing-encryption-key","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"}