{"record":{"id":"7ef139c83fddfb25","repo":"spring-projects/spring-security","slug":"failed-to-deserialize-payload-7ef139","errorCode":null,"errorMessage":"Failed to deserialize payload","messagePattern":"Failed to deserialize payload","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/authentication/logout/OpenSaml5Template.java","lineNumber":160,"sourceCode":"\t@Override\n\tpublic <T extends XMLObject> T deserialize(InputStream serialized) {\n\t\ttry {\n\t\t\tParserPool pool = XMLObjectProviderRegistrySupport.getParserPool();\n\t\t\tAssert.notNull(pool, \"ParserPool must be configured\");\n\t\t\tDocument document = pool.parse(serialized);\n\t\t\tElement element = document.getDocumentElement();\n\t\t\tUnmarshallerFactory factory = XMLObjectProviderRegistrySupport.getUnmarshallerFactory();\n\t\t\tUnmarshaller unmarshaller = factory.getUnmarshaller(element);\n\t\t\tif (unmarshaller == null) {\n\t\t\t\tthrow new Saml2Exception(\"Unsupported element of type \" + element.getTagName());\n\t\t\t}\n\t\t\treturn (T) unmarshaller.unmarshall(element);\n\t\t}\n\t\tcatch (Saml2Exception ex) {\n\t\t\tthrow ex;\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new Saml2Exception(\"Failed to deserialize payload\", ex);\n\t\t}\n\t}\n\n\t@Override\n\tpublic OpenSaml5SerializationConfigurer serialize(XMLObject object) {\n\t\tMarshaller marshaller = XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(object);\n\t\tAssert.notNull(marshaller, \"Marshaller for \" + object.getElementQName() + \" must be configured\");\n\t\ttry {\n\t\t\treturn serialize(marshaller.marshall(object));\n\t\t}\n\t\tcatch (MarshallingException ex) {\n\t\t\tthrow new Saml2Exception(ex);\n\t\t}\n\t}\n\n\t@Override\n\tpublic OpenSaml5SerializationConfigurer serialize(Element element) {\n\t\treturn new OpenSaml5SerializationConfigurer(element);","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/authentication/logout/OpenSaml5Template.java#L142-L178","documentation":"OpenSaml5Template.deserialize() catches any non-Saml2Exception failure while parsing or unmarshalling the payload (ParserPool errors, SAX parse errors for malformed XML, unmarshaller runtime failures) and rewraps it in this Saml2Exception with the original as the cause. It signals the input could not be converted into an OpenSAML XMLObject.","triggerScenarios":"Calling OpenSaml5Template.deserialize(String) with malformed XML: bad encoding, unescaped entities, truncated or doubly-encoded bytes, schema-invalid XML, or when the configured ParserPool fails to parse the string.","commonSituations":"A misbehaving IdP returns truncated or corrupted SAMLResponse; the caller forgot to base64-/URL-decode (or inflate) before deserializing; tampered payloads fail schema validity; wrong charset assumptions (payload is not UTF-8).","solutions":["Verify the input was fully base64-decoded and, for redirect binding, URL-decoded and inflated before deserializing.","Catch this Saml2Exception and inspect ex.getCause() (usually a SAXParseException) for the exact malformed location.","Log the raw payload (at debug) to spot truncation/encoding corruption; re-fetch if transient.","Reject the request as a protocol violation rather than retrying unmodified input."],"exampleFix":"// before\nResponse r = template.deserialize(request.getParameter(\"SAMLResponse\"));\n// Saml2Exception: Failed to deserialize payload (caused by: Content is not allowed in prolog)\n// after\nbyte[] decoded = Saml2Utils.samlDecode(request.getParameter(\"SAMLResponse\"));\nString xml = Saml2Utils.samlInflate(decoded); // redirect binding\ntry {\n    Response r = template.deserialize(xml);\n} catch (Saml2Exception ex) {\n    logger.warn(\"Malformed SAML payload\", ex.getCause());\n    throw new AuthenticationServiceException(\"Invalid SAMLResponse\", ex);\n}","handlingStrategy":"try-catch","validationCode":"String trimmed = xml == null ? \"\" : xml.trim();\nif (!trimmed.startsWith(\"<\")) {\n    throw new IllegalArgumentException(\"Payload is not XML; check base64/inflate decoding steps\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    T obj = template.deserialize(xml);\n} catch (Saml2Exception ex) {\n    Throwable cause = ex.getCause();\n    logger.warn(\"SAML deserialize failed: {}\", cause == null ? ex.getMessage() : cause.getMessage());\n    throw new AuthenticationServiceException(\"Malformed SAML payload\", ex);\n}","preventionTips":["Complete the full decode chain (URL-decode -> base64-decode -> inflate) before deserializing.","Log ex.getCause() (SAXParseException has line/column) to pinpoint malformed XML.","Verify charset is UTF-8 end to end.","Reject and count malformed payloads per IdP to detect misbehaving partners."],"tags":["saml2","opensaml","xml-parse","deserialization"],"backgroundTag":"xml-unmarshal-failed","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"}