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 and asks OpenSAML's UnmarshallerFactory for an unmarshaller for the root element. If none is registered for that element's QName/tagName, Spring Security throws this Saml2Exception because it cannot convert the raw DOM element into an OpenSAML XMLObject.
Source
Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/authentication/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
- Ensure the input is a valid SAML document whose root element is a SAML protocol element (e.g. saml2p:Response, saml2p:LogoutResponse) in the correct namespace.
- Call OpenSamlInitializationService.initialize() before deserializing so default unmarshallers are registered.
- Validate/inspect the serialized payload's root tag name (reported in the message) to find what is actually being fed in — often an upstream error page or proxy-rewritten XML.
- Check classpath for mixed OpenSAML 4/5 jars and remove the old ones so unmarshallers register in the active registry.
Example fix
// before
String body = new String(responseBytes); // may be an HTML error page
Response r = template.deserialize(body);
// after
OpenSamlInitializationService.initialize();
if (!body.contains("urn:oasis:names:tc:SAML:2.0:protocol")) {
throw new Saml2Exception("Not a SAML protocol document: " + body.substring(0, Math.min(80, body.length())));
}
Response r = template.deserialize(body); Defensive patterns
Strategy: validation
Validate before calling
if (!serialized.trim().startsWith("<") || !serialized.contains("urn:oasis:names:tc:SAML")) {
throw new IllegalArgumentException("Payload is not a SAML XML document");
} Try / catch
try { return template.deserialize(serialized); } catch (Saml2Exception ex) { log.warn("Unsupported SAML root element: {}", ex.getMessage()); throw new InvalidSamlPayloadException(ex); } Prevention
- Inspect the root tag name reported in the message when debugging
- Decode Base64/URL encodings before deserializing
- Reject non-XML payloads (HTML error pages) early
When it happens
Trigger: Calling OpenSaml5Template.deserialize(String) whose document root element has no registered OpenSAML unmarshaller — factory.getUnmarshaller(element) returns null (message includes the root element's tag name).
Common situations: Deserializing non-SAML or malformed XML (wrong root element, HTML error page, SOAP envelope instead of SAML message); feeding a truncated/modified SAML response; registry not initialized before parsing; wrong namespace on the root element (e.g. stripped or rewritten by a proxy).
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
- Spring Security does not support OpenSAML {Version.getVersio
- Spring Security does not support OpenSAML {Version.getVersio
- Saml2Exception wrapping MarshallingException while re-marsha
- Unable to resolve Builder for
- Failed to deserialize payload
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/066f50869d78e510.
Report an issue: GitHub.