spring-projects/spring-security · error · Saml2Exception
Saml2Exception wrapping exception from signature signing…
Error message
Saml2Exception wrapping exception from signature signing parameters resolution (see also Assert: "Failed to resolve any signing credential")
What it means
This Saml2Exception wraps any failure that occurs while resolving SignatureSigningParameters, and is also thrown directly (as an assert) when the resolver returns null. The library throws it because it cannot produce a valid signing credential/algorithm configuration needed to sign SAML messages (auth requests, responses, metadata). Without signing parameters, outgoing SAML payloads cannot be secured.
Solutions
- Add at least one signing credential to the RelyingPartyRegistration: registration.signingX509Credentials(c -> c.add(signingCredential)).
- Verify the private key/certificate pair loads correctly (correct PEM format, no password mismatch) before building the registration.
- Check that a SignatureSigningParametersResolver is configured on the template/processor and that its criteria (algorithms, digest, canonicalization) are satisfiable.
- Inspect the wrapped cause (ex.getCause()) for the real resolver failure, e.g. KeyStore or PKCS issues.
Example fix
// before
RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("idp").build();
// after
RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("idp")
.signingX509Credentials(c -> c.add(new Saml2X509Credential(privateKey, certificate, Saml2X509CredentialType.SIGNING)))
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (registration.getSigningX509Credentials().isEmpty()) {
throw new IllegalStateException("No signing credentials configured for " + registration.getRegistrationId());
} Try / catch
try {
SignatureSigningParameters p = template.resolveSigningParameters(context);
} catch (Saml2Exception ex) {
logger.error("Signing credential resolution failed", ex.getCause());
} Prevention
- Always register at least one SIGNING Saml2X509Credential per relying party.
- Smoke-test PEM key parsing in integration tests before deploy.
- Log wrapped causes (ex.getCause()) to catch credential loading issues early.
When it happens
Trigger: Calling OpenSaml5Template.resolveSigningParameters (via parameters(...)) when no SignatureSigningParametersResolver matches the criteria, or when the underlying resolver (e.g. DefaultSignatureSigningParametersResolver) throws while evaluating credentials.
Common situations: Relying party configured with no signing credentials in RelyingPartyRegistration (signingX509Credentials empty); private key cannot be read/decoded; signing algorithm/bignum config mismatch after upgrading to OpenSAML 5; metadata signing enabled without credentials.
Related errors
- Saml2Exception wrapping DecryptionException during…
- Saml2Exception wrapping DecryptionException during…
- Saml2Exception wrapping DecryptionException during…
- Saml2Exception wrapping DecryptionException during…
- Saml2Exception wrapping DecryptionException during…
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/dd5385cb8083276f.
Report an issue: GitHub.
Appendix: source
Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/metadata/OpenSaml5Template.java:302
private SignatureSigningParameters resolveSigningParameters() {
List<Credential> credentials = resolveSigningCredentials();
List<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);
String canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
SignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();
BasicSignatureSigningConfiguration signingConfiguration = new BasicSignatureSigningConfiguration();
signingConfiguration.setSigningCredentials(credentials);
signingConfiguration.setSignatureAlgorithms(this.algs);
signingConfiguration.setSignatureReferenceDigestMethods(digests);
signingConfiguration.setSignatureCanonicalizationAlgorithm(canonicalization);
signingConfiguration.setKeyInfoGeneratorManager(buildSignatureKeyInfoGeneratorManager());
CriteriaSet criteria = new CriteriaSet(new SignatureSigningConfigurationCriterion(signingConfiguration));
try {
SignatureSigningParameters parameters = resolver.resolveSingle(criteria);
Assert.notNull(parameters, "Failed to resolve any signing credential");
return parameters;
}
catch (Exception ex) {
throw new Saml2Exception(ex);
}
}
private NamedKeyInfoGeneratorManager buildSignatureKeyInfoGeneratorManager() {
final NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager();
namedManager.setUseDefaultManager(true);
final KeyInfoGeneratorManager defaultManager = namedManager.getDefaultManager();
// Generator for X509Credentials
final X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory();
x509Factory.setEmitEntityCertificate(true);
x509Factory.setEmitEntityCertificateChain(true);
defaultManager.registerFactory(x509Factory);
return namedManager;
}View on GitHub (pinned to 96852e8860)