{"record":{"id":"e0791a6fa9c1e5eb","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-exception-from-signature-s-e0791a","errorCode":null,"errorMessage":"Saml2Exception wrapping exception from signature signing parameters resolution (see also Assert: \"Failed to resolve any signing credential\")","messagePattern":"Saml2Exception wrapping exception from signature signing parameters resolution \\(see also Assert: \"Failed to resolve any signing credential\"\\)","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/OpenSaml5Template.java","lineNumber":302,"sourceCode":"\t\tprivate SignatureSigningParameters resolveSigningParameters() {\n\t\t\tList<Credential> credentials = resolveSigningCredentials();\n\t\t\tList<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);\n\t\t\tString canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;\n\t\t\tSignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();\n\t\t\tBasicSignatureSigningConfiguration signingConfiguration = new BasicSignatureSigningConfiguration();\n\t\t\tsigningConfiguration.setSigningCredentials(credentials);\n\t\t\tsigningConfiguration.setSignatureAlgorithms(this.algs);\n\t\t\tsigningConfiguration.setSignatureReferenceDigestMethods(digests);\n\t\t\tsigningConfiguration.setSignatureCanonicalizationAlgorithm(canonicalization);\n\t\t\tsigningConfiguration.setKeyInfoGeneratorManager(buildSignatureKeyInfoGeneratorManager());\n\t\t\tCriteriaSet criteria = new CriteriaSet(new SignatureSigningConfigurationCriterion(signingConfiguration));\n\t\t\ttry {\n\t\t\t\tSignatureSigningParameters parameters = resolver.resolveSingle(criteria);\n\t\t\t\tAssert.notNull(parameters, \"Failed to resolve any signing credential\");\n\t\t\t\treturn parameters;\n\t\t\t}\n\t\t\tcatch (Exception ex) {\n\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t}\n\t\t}\n\n\t\tprivate NamedKeyInfoGeneratorManager buildSignatureKeyInfoGeneratorManager() {\n\t\t\tfinal NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager();\n\n\t\t\tnamedManager.setUseDefaultManager(true);\n\t\t\tfinal KeyInfoGeneratorManager defaultManager = namedManager.getDefaultManager();\n\n\t\t\t// Generator for X509Credentials\n\t\t\tfinal X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory();\n\t\t\tx509Factory.setEmitEntityCertificate(true);\n\t\t\tx509Factory.setEmitEntityCertificateChain(true);\n\n\t\t\tdefaultManager.registerFactory(x509Factory);\n\n\t\t\treturn namedManager;\n\t\t}","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/OpenSaml5Template.java#L284-L320","documentation":"During signature signing parameter resolution, any exception thrown by the resolver is rethrown as Saml2Exception. Additionally, if the resolver yields no SignatureSigningParameters at all, Spring's Assert fails with 'Failed to resolve any signing credential' which is then wrapped the same way. It means the template could not find any credential eligible for signing under the given criteria.","triggerScenarios":"Calling sign()/parameters() when RelyingPartyRegistration has no signing credentials configured (no private key in the registration) or no credential satisfies SignatureSigningParametersResolver criteria (e.g. credential is encryption-only or algorithm allow-list excludes it).","commonSituations":"RelyingPartyRegistration built via registrationId(...) without signWithX509PrivateKey/assertingParty signing setup; credentials marked for encryption only; OpenSAML signing configuration (algorithms) excluding the configured key.","solutions":["Configure a signing credential on the RelyingPartyRegistration (signWithX509PrivateKey or signWith(SignatureAlgorithm, credential))","Verify credentials are not consumed solely for decryption/assertion signing","Check that the signing algorithm allow-list includes an algorithm compatible with the credential","Catch Saml2Exception and inspect the wrapped cause / assertion message"],"exampleFix":"// before\nRelyingPartyRegistration.withRegistrationId(\"idp\") // no signing credential\n// after\n.signWithX509PrivateKey(privateKey, certificateChain)\n.build()","handlingStrategy":"validation","validationCode":"List<Saml2X509Credential> signing = registration.getSigningX509Credentials();\nif (signing.isEmpty()) throw new Saml2ConfigurationException(\"No signing credential on RelyingPartyRegistration \" + id);","typeGuard":null,"tryCatchPattern":"try { params = template.parameters(criteria); } catch (Saml2Exception e) { throw new Saml2ConfigurationException(\"Resolve signing params: \" + e.getMessage(), e); }","preventionTips":["Call signWithX509PrivateKey/signWith when building every RelyingPartyRegistration","Fail fast at configuration time by resolving signing parameters once at startup","Keep the signature algorithm allow-list aligned with registered key types"],"tags":["saml","signature","configuration","spring-security"],"backgroundTag":"missing-credentials","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}