{"record":{"id":"31d18ae0ba873dc7","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-exception-while-signing-xm","errorCode":null,"errorMessage":"Saml2Exception wrapping exception while signing XMLObject","messagePattern":"Saml2Exception wrapping exception while signing XMLObject","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java","lineNumber":252,"sourceCode":"\n\t\tOpenSaml5SignatureConfigurer(Collection<Saml2X509Credential> credentials) {\n\t\t\tthis.credentials = credentials;\n\t\t}\n\n\t\t@Override\n\t\tpublic OpenSaml5SignatureConfigurer algorithms(List<String> algs) {\n\t\t\tthis.algs = algs;\n\t\t\treturn this;\n\t\t}\n\n\t\t@Override\n\t\tpublic <O extends SignableXMLObject> O sign(O object) {\n\t\t\tSignatureSigningParameters parameters = resolveSigningParameters();\n\t\t\ttry {\n\t\t\t\tSignatureSupport.signObject(object, 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\treturn object;\n\t\t}\n\n\t\t@Override\n\t\tpublic Map<String, String> sign(Map<String, String> params) {\n\t\t\tSignatureSigningParameters parameters = resolveSigningParameters();\n\t\t\tthis.components.putAll(params);\n\t\t\tCredential credential = parameters.getSigningCredential();\n\t\t\tAssert.notNull(credential, \"credential cannot be null when signing a SAML payload\");\n\t\t\tString algorithmUri = parameters.getSignatureAlgorithm();\n\t\t\tAssert.notNull(algorithmUri, \"algorithmUri cannot be null when signing a SAML payload\");\n\t\t\tthis.components.put(Saml2ParameterNames.SIG_ALG, algorithmUri);\n\t\t\tUriComponentsBuilder builder = UriComponentsBuilder.newInstance();\n\t\t\tfor (Map.Entry<String, String> component : this.components.entrySet()) {\n\t\t\t\tbuilder.queryParam(component.getKey(),\n\t\t\t\t\t\tUriUtils.encode(component.getValue(), StandardCharsets.ISO_8859_1));\n\t\t\t}","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java#L234-L270","documentation":"The template's sign(SignableXMLObject) method resolves SignatureSigningParameters and delegates to OpenSAML's SignatureSupport.signObject; any exception during signing is wrapped in this Saml2Exception. Root causes are usually credential problems (wrong key type, inaccessible private key) or invalid/unsupported signature algorithm configuration.","triggerScenarios":"Calling sign(signableObject) when resolveSigningParameters yields parameters with a signing credential that cannot be used (e.g. credential lacks a private key), an unsupported signature algorithm URI, or keystore access fails inside signObject.","commonSituations":"Signing credential loaded from a JKS/PKCS12 keystore with wrong password; certificate/key pair mismatch; configuring a signature algorithm the JVM provider does not support; OpenSAML SignatureSigningParameters misconfigured by a custom resolver.","solutions":["Inspect ex.getCause() for the underlying signing failure (KeyException, NoSuchAlgorithmException, etc.)","Verify the signing credential contains a private key and the password/keystore config is correct","Confirm the configured signature algorithm URI is supported by the JVM's crypto providers","Ensure SignatureSigningParametersResolver returns a complete parameter set (credential + signatureAlgorithm + signatureCanonicalizationAlgorithm + KeyInfoGeneratorManager)"],"exampleFix":"// before\nsigningCredential = new BasicCredential(cert); // no private key\n// after\nsigningCredential = new BasicCredential(cert, privateKey); // credential must include private key for signing","handlingStrategy":"try-catch","validationCode":"// ensure credential is signing-capable before sign()\nAssert.notNull(privateKey, \"Signing credential must contain a private key\");\nAssert.isTrue(SignatureSupport.isCompatibleSignatureAlgorithms(algorithmUri, credential.getPublicKey()),\n    \"Algorithm incompatible with key\");","typeGuard":null,"tryCatchPattern":"try {\n    return template.sign(signableObject);\n} catch (Saml2Exception ex) {\n    logger.error(\"Signing failed: \" + ex.getCause(), ex);\n    throw ex;\n}","preventionTips":["Verify the keystore password and private key access at startup, not at first sign","Match signature algorithm URI to the key type (RSA vs EC)","Test signing in CI with the production-equivalent credential"],"tags":["saml2","opensaml","signing","credential"],"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"}