{"record":{"id":"dd5385cb8083276f","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-exception-from-signature-s","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/metadata/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/metadata/OpenSaml5Template.java#L284-L320","documentation":"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.","triggerScenarios":"Calling OpenSaml5Template.resolveSigningParameters (via parameters(...)) when no SignatureSigningParametersResolver matches the criteria, or when the underlying resolver (e.g. DefaultSignatureSigningParametersResolver) throws while evaluating credentials.","commonSituations":"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.","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."],"exampleFix":"// before\nRelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId(\"idp\").build();\n// after\nRelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId(\"idp\")\n    .signingX509Credentials(c -> c.add(new Saml2X509Credential(privateKey, certificate, Saml2X509CredentialType.SIGNING)))\n    .build();","handlingStrategy":"validation","validationCode":"if (registration.getSigningX509Credentials().isEmpty()) {\n    throw new IllegalStateException(\"No signing credentials configured for \" + registration.getRegistrationId());\n}","typeGuard":null,"tryCatchPattern":"try {\n    SignatureSigningParameters p = template.resolveSigningParameters(context);\n} catch (Saml2Exception ex) {\n    logger.error(\"Signing credential resolution failed\", ex.getCause());\n}","preventionTips":["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."],"tags":["saml2","signing","credential-resolution","opensaml5"],"backgroundTag":"missing-credentials","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}