apereo/cas · error
Unable to resolve the encryption [public] key for entity id
Error message
Unable to resolve the encryption [public] key for entity id [{}] What it means
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.
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
Example fix
// before (JSON/YAML service config) "encryptionOptional": false // after "encryptionOptional": true
Defensive patterns
Strategy: validation
Validate before calling
// Before building the encrypter, verify the SP metadata exposes an encryption key
val criteria = new CriteriaSet(
new EntityIdCriterion(peerEntityId),
new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
val cred = mdCredentialResolver.resolveSingle(criteria);
if (cred == null || cred.getPublicKey() == null) {
// inspect service metadata or set encryptionOptional before proceeding
} Try / catch
try {
encrypter = buildEncrypterForSamlObject(...);
} catch (SamlException e) {
// key unresolved for peer entity: fall back to unsigned/unencrypted or fail request
LOGGER.error("No encryption key for entity [{}]", peerEntityId, e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Expired or invalid certificate in metadata for
- Unable to encrypt assertion for
- Unable to resolve the encryption [public] key for entity id
- Required NameID format
- No Certificates provided
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/c4e80bd422b902e7.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/builders/enc/SamlIdPObjectEncrypter.java:328
val roleDescriptorResolver = SamlIdPUtils.getRoleDescriptorResolver(adaptor,
samlIdPProperties.getMetadata().getCore().isRequireValidMetadata());
mdCredentialResolver.setRoleDescriptorResolver(roleDescriptorResolver);
mdCredentialResolver.initialize();
val criteriaSet = new CriteriaSet();
criteriaSet.add(new EncryptionConfigurationCriterion(encryptionConfiguration));
criteriaSet.add(new EntityIdCriterion(peerEntityId));
criteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
criteriaSet.add(new UsageCriterion(UsageType.ENCRYPTION));
criteriaSet.add(new SamlIdPSamlRegisteredServiceCriterion(service));
LOGGER.debug("Attempting to resolve the encryption key for entity id [{}]", peerEntityId);
val credential = mdCredentialResolver.resolveSingle(criteriaSet);
if (credential == null || credential.getPublicKey() == null) {
if (service.isEncryptionOptional()) {
LOGGER.warn("Unable to resolve the encryption [public] key for entity id [{}]", peerEntityId);
return null;
}
throw new SamlException("Unable to resolve the encryption [public] key for entity id " + peerEntityId);
}
val encodedKey = EncodingUtils.encodeBase64(credential.getPublicKey().getEncoded());
LOGGER.debug("Found encryption public key: [{}]", encodedKey);
encryptionConfiguration.setKeyTransportEncryptionCredentials(CollectionUtils.wrapList(credential));
return credential;
}
/**
* Resolve encryption parameters.
*
* @param service the service
* @param encryptionConfiguration the encryption configuration
* @return the encryption parameters
* @throws ResolverException the exceptionView on GitHub (pinned to e7288fc434)