apereo/cas · error · SamlException
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
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.
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.
Example fix
// before <md:KeyDescriptor use="signing">...</md:KeyDescriptor> <!-- only signing key in SP metadata --> // after <md:KeyDescriptor use="encryption"><ds:KeyInfo><ds:X509Data>...</ds:X509Data></ds:KeyInfo></md:KeyDescriptor>
Defensive patterns
Strategy: try-catch
Validate before calling
val credential = metadataResolver.getEncryptionCredential(peerEntityId, service);
if ((credential == null || credential.getPublicKey() == null) && !service.isEncryptionOptional())
throw new IllegalStateException("No encryption public key for " + peerEntityId + "; fix SP metadata first"); Type guard
boolean hasEncryptionKey(Credential c) { return c != null && c.getPublicKey() != null; } Try / catch
try {
val encCred = encrypter.configureKeyEncryptionCredential(peerEntityId, service, adaptor);
if (encCred == null) LOGGER.warn("Encryption skipped (optional) for {}", peerEntityId);
} catch (SamlException e) {
LOGGER.error("SP [{}] has no encryption key in metadata; request updated metadata", peerEntityId, e);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to encrypt assertion for
- Unable to resolve the encryption [public] key for entity id
- No assertion consumer service could be found for entity
- Endpoint for is not available or does not define a binding…
- Endpoint for does not define a binding or location for…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/58de793bd8832c78.
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:331
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 exception
*/
protected EncryptionParameters resolveEncryptionParameters(final SamlRegisteredService service,
final BasicEncryptionConfiguration encryptionConfiguration)View on GitHub (pinned to e7288fc434)