spring-projects/spring-security · error · Saml2Exception

Failed to deserialize payload

Error message

Failed to deserialize payload

What it means

OpenSaml5Template.deserialize wraps any non-Saml2Exception failure during XML parsing or unmarshalling (e.g. SAX parse errors, IOException, ClassCastException from a mis-typed build) into Saml2Exception('Failed to deserialize payload') with the original as the cause.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/internal/OpenSaml5Template.java:160

	@Override
	public <T extends XMLObject> T deserialize(InputStream serialized) {
		try {
			ParserPool pool = XMLObjectProviderRegistrySupport.getParserPool();
			Assert.notNull(pool, "ParserPool must be configured");
			Document document = pool.parse(serialized);
			Element element = document.getDocumentElement();
			UnmarshallerFactory factory = XMLObjectProviderRegistrySupport.getUnmarshallerFactory();
			Unmarshaller unmarshaller = factory.getUnmarshaller(element);
			if (unmarshaller == null) {
				throw new Saml2Exception("Unsupported element of type " + element.getTagName());
			}
			return (T) unmarshaller.unmarshall(element);
		}
		catch (Saml2Exception ex) {
			throw ex;
		}
		catch (Exception ex) {
			throw new Saml2Exception("Failed to deserialize payload", ex);
		}
	}

	@Override
	public OpenSaml5SerializationConfigurer serialize(XMLObject object) {
		Marshaller marshaller = XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(object);
		Assert.notNull(marshaller, "Marshaller for " + object.getElementQName() + " must be configured");
		try {
			return serialize(marshaller.marshall(object));
		}
		catch (MarshallingException ex) {
			throw new Saml2Exception(ex);
		}
	}

	@Override
	public OpenSaml5SerializationConfigurer serialize(Element element) {
		return new OpenSaml5SerializationConfigurer(element);

View on GitHub (pinned to 96852e8860)

Solutions

  1. Read the cause exception attached to this Saml2Exception — it identifies the exact parse/unmarshall failure (line, column, or type problem).
  2. Log and inspect the raw payload before deserialization; ensure the SAML message was correctly base64-decoded and URL-decoded exactly once.
  3. Verify the sender is producing well-formed XML matching the SAML schema (no truncation, no HTML error content).
  4. If the cause is ClassCastException or missing type info, confirm the element is the type your caller expects before calling deserialize.

Example fix

// before: double-decoding corrupts payload
String xml = new String(Base64.getDecoder().decode(
        URLDecoder.decode(samlRequest, StandardCharsets.UTF_8)));
// after: decode base64 only — container already URL-decoded parameters
String xml = new String(Base64.getDecoder().decode(samlRequest), StandardCharsets.UTF_8);
Defensive patterns

Strategy: try-catch

Validate before calling

try {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    dbf.newDocumentBuilder().parse(new InputSource(new StringReader(serialized)));
} catch (SAXException | IOException e) {
    throw new IllegalArgumentException("Payload is not well-formed XML", e);
}

Try / catch

try {
    return template.deserialize(serialized);
} catch (Saml2Exception ex) {
    log.error("Deserialization failed", ex.getCause());
    throw new Saml2ErrorStatusException(HttpStatus.BAD_REQUEST, ex.getCause());
}

Prevention

When it happens

Trigger: deserialize(String/InputStream) is given malformed XML, truncated payload, wrong encoding, or content that parses but fails during unmarshall — any checked Exception other than Saml2Exception in the try block.

Common situations: Payload corrupted in transit (URL-decoding issues, whitespace/truncation from logging or trimming); base64-decoded SAML message re-encoded incorrectly; XML with invalid characters or DTDs; wrong charset; passing HTML error pages saved as XML.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/7503daa3e9fd12a1. Report an issue: GitHub.