{"record":{"id":"58de793bd8832c78","repo":"apereo/cas","slug":"unable-to-resolve-the-encryption-public-key-for","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":"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":331,"sourceCode":"        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\n     */\n    protected EncryptionParameters resolveEncryptionParameters(final SamlRegisteredService service,\n                                                               final BasicEncryptionConfiguration encryptionConfiguration)","sourceCodeStart":313,"sourceCodeEnd":349,"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#L313-L349","documentation":"While building the encrypter, configureKeyEncryptionCredential resolves the SP peer's encryption public key. If the credential or its public key is null (SP metadata has no encryption key), the method returns null when encryption is optional, otherwise throws SamlException naming the peer entityID.","triggerScenarios":"buildEncrypterForSamlObject → configureKeyEncryptionCredential is called for a peer entity whose metadata/key source yields no credential or a credential with null publicKey, and service.isEncryptionOptional() is false.","commonSituations":"SP metadata missing KeyDescriptor use=encryption; stale/misindexed metadata so the SP's encryption cert isn't found; entityID mismatch causing lookup against the wrong entity; service requiring encryption though SP never published an encryption key.","solutions":["Publish an encryption certificate in the SP metadata (KeyDescriptor use=\"encryption\") and refresh CAS's metadata cache.","Set encryptionOptional=true on the registered service if unencrypted assertions are acceptable.","Confirm the peerEntityId used for the lookup matches the SP's entityID in metadata.","Check the metadata adaptor (file/MDQ/Dynamic) actually contains the SP entry with its certificate."],"exampleFix":"// before\n<md:KeyDescriptor use=\"signing\">...</md:KeyDescriptor> <!-- only signing key in SP metadata -->\n// after\n<md:KeyDescriptor use=\"encryption\"><ds:KeyInfo><ds:X509Data>...</ds:X509Data></ds:KeyInfo></md:KeyDescriptor>","handlingStrategy":"try-catch","validationCode":"val credential = metadataResolver.getEncryptionCredential(peerEntityId, service);\nif ((credential == null || credential.getPublicKey() == null) && !service.isEncryptionOptional())\n    throw new IllegalStateException(\"No encryption public key for \" + peerEntityId + \"; fix SP metadata first\");","typeGuard":"boolean hasEncryptionKey(Credential c) { return c != null && c.getPublicKey() != null; }","tryCatchPattern":"try {\n    val encCred = encrypter.configureKeyEncryptionCredential(peerEntityId, service, adaptor);\n    if (encCred == null) LOGGER.warn(\"Encryption skipped (optional) for {}\", peerEntityId);\n} catch (SamlException e) {\n    LOGGER.error(\"SP [{}] has no encryption key in metadata; request updated metadata\", peerEntityId, e);\n}","preventionTips":["Validate SP metadata contains KeyDescriptor use=\"encryption\" at onboarding time.","Confirm entityID matches exactly between service registration and SP metadata.","Re-fetch metadata after the SP rotates its encryption certificate.","Document encryption requirements for SP integrators."],"tags":["saml","encryption","public-key","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"}