apereo/cas · error · SamlException
Signing credentials for validation could not be resolved…
Error message
Signing credentials for validation could not be resolved based on the provided signature
What it means
In validateSignatureOnProfileRequest, the signature itself was already cryptographically validated, but the validator then re-resolves the signing credential(s) for the peer via getSigningCredential. If none resolve from the role descriptor resolver, this SamlException is thrown. It indicates the peer's metadata does not expose a usable signing credential matching the provided signature.
Solutions
- Ensure the peer metadata publishes the exact certificate used to sign as a signing KeyDescriptor
- Reload/refresh the peer metadata so the current signing cert is available
- Verify the issuer entity ID in the request matches a loaded metadata record
- Check SAML service registration (metadata location, entity ID regex) resolves this issuer
- If keys were rolled over, keep the old cert in metadata until all peers have switched
Example fix
// before: request signed with unpublished key, resolver finds nothing credentials.isEmpty() -> throw SamlException(...) // after: publish the signing cert in the peer's metadata <KeyDescriptor use="signing"><ds:KeyInfo><ds:X509Data><ds:X509Certificate>...(cert matching signature key)...</ds:X509Certificate></ds:X509Data></ds:KeyInfo></KeyDescriptor>
Defensive patterns
Strategy: validation
Validate before calling
// ensure the signing key is published in peer metadata before sending signed profile requests val cert = X509Support.decodeCertificate(peerSigningCert); assert peerMetadataSigningCerts.stream().anyMatch(c -> c.equals(cert)) : "Signing cert not in peer metadata";
Prevention
- Always sign with keys published in your metadata; keep rollovers staged (publish before signing)
- Reload metadata after key rollover on both sides
- Log the issuer entity ID on signature failures to spot entity-ID mismatches quickly
When it happens
Trigger: verifySamlProfileRequest -> validateSignatureOnProfileRequest when getSigningCredential(roleDescriptorResolver, profileRequest) returns empty after signature validation: peer metadata has no signing KeyDescriptor, credentials don't match the signing key, or the issuer/entity ID is not in the metadata provider.
Common situations: IdP-initiated or profile requests from a peer whose metadata lacks signing certs; metadata staleness after key rollover (old cert removed before CAS reloaded); entity ID typo so the resolver finds no role descriptor; signing with a key not published in metadata.
Related errors
- Signing credentials for validation could not be resolved
- Unable to locate signing credentials
- Unable to identify the public key from the signing…
- Logout request is not signed but should be for service
- Resource [ ] cannot be located
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/8cbfe6d5a533bcc2.
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/validate/SamlObjectSignatureValidator.java:207
FunctionUtils.throwIf(!foundValidCredential, () -> {
LOGGER.error("No valid credentials could be found to verify the signature for [{}]", profileRequest.getIssuer());
return new SamlException("No valid signing credentials for authentication request validation could be resolved");
});
return true;
}
private boolean validateSignatureOnProfileRequest(final RequestAbstractType profileRequest,
final Signature signature,
final RoleDescriptorResolver roleDescriptorResolver) throws Throwable {
val validator = new SAMLSignatureProfileValidator();
LOGGER.debug("Validating profile signature for [{}] via [{}]...", profileRequest.getIssuer(),
validator.getClass().getSimpleName());
validator.validate(signature);
LOGGER.debug("Successfully validated profile signature for [{}].", profileRequest.getIssuer());
val credentials = getSigningCredential(roleDescriptorResolver, profileRequest);
if (credentials.isEmpty()) {
throw new SamlException("Signing credentials for validation could not be resolved based on the provided signature");
}
var foundValidCredential = false;
val it = credentials.iterator();
while (!foundValidCredential && it.hasNext()) {
try {
val credential = it.next();
LOGGER.debug("Validating signature using credentials for [{}]", credential.getEntityId());
SignatureValidator.validate(signature, credential);
LOGGER.info("Successfully validated the request signature.");
foundValidCredential = true;
} catch (final Exception e) {
LOGGER.debug(e.getMessage(), e);
}
}
FunctionUtils.throwIf(!foundValidCredential, () -> {
LOGGER.error("No valid credentials could be found to verify the signature for [{}]", profileRequest.getIssuer());View on GitHub (pinned to e7288fc434)