spring-projects/spring-security · error · Saml2Exception

Unsupported element of type

Error message

Unsupported element of type 

What it means

OpenSaml5Template.deserialize() parses the XML string, finds the root element, and asks the OpenSAML UnmarshallerFactory for an Unmarshaller matching that element. If OpenSAML has no unmarshaller registered for the element's QName, the payload cannot be mapped to an XMLObject and this Saml2Exception is thrown. It indicates the XML root is not a registered SAML element (or providers were not initialized).

Source

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

		return (T) builder.buildObject(elementName);
	}

	@Override
	public <T extends XMLObject> T deserialize(String serialized) {
		return deserialize(new ByteArrayInputStream(serialized.getBytes(StandardCharsets.UTF_8)));
	}

	@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));
		}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Verify the input string's root element is a SAML element (e.g. samlp:Response) — log or validate the root tag name before deserializing
  2. Ensure OpenSAML is initialized (default providers registered) and opensaml-saml-impl is on the classpath
  3. Strip any wrapper elements (SOAP envelopes, HTML) so the root is the SAML element itself
  4. Check for duplicate/conflicting OpenSAML versions on the classpath

Example fix

// before
Assertion assertion = template.deserialize(htmlErrorPage);
// after
if (!htmlErrorPage.trim().startsWith("<saml2:")) {
    throw new Saml2Exception("Not a SAML document");
}
Assertion assertion = template.deserialize(samlXmlString);
Defensive patterns

Strategy: validation

Validate before calling

String trimmed = serialized.trim();
if (!(trimmed.startsWith("<") && (trimmed.contains("urn:oasis:names:tc:SAML")))) {
    throw new IllegalArgumentException("Not a SAML document");
}

Try / catch

try {
    return template.deserialize(xml);
} catch (Saml2Exception ex) {
    logger.warn("Unrecognized/unsupported SAML root element", ex);
    return null;
}

Prevention

When it happens

Trigger: Calling template.deserialize(String) where the root element is not a known OpenSAML element — e.g. an error page, HTML, or a wrapped SOAP envelope instead of a SAML Response/Assertion — or when OpenSAML providers are not initialized.

Common situations: Passing raw IdP HTML error pages or logout HTML to deserialize; wrapping the SAML message in an extra element; missing opensaml-saml-impl dependency so unmarshallers for SAML elements are never registered.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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