{"record":{"id":"86fe4ac53d93583e","repo":"spring-projects/spring-security","slug":"failed-to-deserialize-payload-86fe4a","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/registration/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/registration/OpenSaml5Template.java#L142-L178","documentation":"OpenSaml5Template.deserialize() wraps any non-Saml2Exception failure — XML parse errors, unmarshalling failures — from parsing or unmarshalling the payload in this Saml2Exception, preserving the cause. It means the input string is not well-formed XML or cannot be unmarshalled into an OpenSAML object tree.","triggerScenarios":"template.deserialize(String) receiving malformed XML (unclosed tags, bad encoding, base64-decoding done wrong so the string is garbage), an XML document that fails schema-level unmarshalling, or IO/parser configuration errors from the ParserPool.","commonSituations":"Forgetting to Base64-decode a SAMLResponse form parameter before deserializing; IdP returning an HTML error page; truncated or whitespace-corrupted SAML POST payload; XML with undeclared entity/namespace prefixes.","solutions":["Decode the input first: new String(Base64.getMimeDecoder().decode(b64), StandardCharsets.UTF_8) before calling deserialize","Inspect ex.getCause() to see the exact parse/unmarshall failure and fix the payload accordingly","Validate the payload is well-formed XML (e.g. parse with a plain DOM parser) before handing it to the template","Reject HTML/error responses from the IdP early instead of attempting to deserialize them"],"exampleFix":"// before\nResponse response = template.deserialize(request.getParameter(\"SAMLResponse\"));\n// after\nString xml = new String(Base64.getMimeDecoder().decode(request.getParameter(\"SAMLResponse\")), StandardCharsets.UTF_8);\nResponse response = template.deserialize(xml);","handlingStrategy":"try-catch","validationCode":"boolean isBase64Xml(String b64) {\n    try {\n        String xml = new String(Base64.getMimeDecoder().decode(b64), StandardCharsets.UTF_8);\n        return xml.trim().startsWith(\"<\");\n    } catch (IllegalArgumentException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return template.deserialize(input);\n} catch (Saml2Exception ex) {\n    logger.warn(\"Failed to deserialize payload; cause=\" + ex.getCause(), ex);\n    throw new BadSamlMessageException(ex);\n}","preventionTips":["Always Base64-decode SAML POST parameters before deserializing","Never feed HTML error pages to deserialize; check Content-Type / first bytes first","Inspect and log ex.getCause() to identify malformed XML early"],"tags":["saml2","opensaml","deserialization","xml-parse"],"backgroundTag":"json-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"}