spring-projects/spring-security · error · Saml2Exception
Unsupported element of type
Error message
Unsupported element of type
What it means
OpenSaml5Template.deserialize parses the serialized XML and asks the OpenSAML UnmarshallerFactory for an Unmarshaller matching the root element. When OpenSAML has no unmarshaller registered for that element's QName, the template throws Saml2Exception('Unsupported element of type <tagName>') — the payload is not a SAML element OpenSaml5 knows how to unmarshal.
Source
Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/internal/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
- Inspect the serialized payload's root element namespace/tag and confirm it is a valid SAML element in the core protocol namespace.
- Ensure OpenSAML initialization ran (OpenSamlInitializationService.initialize()) so unmarshaller factories are populated.
- If you use custom SAML extension elements, register their unmarshallers with XMLObjectProviderRegistrySupport before deserializing.
- Check that you are not decrypting/peeling the wrong layer (e.g. passing an EncryptedAssertion instead of the decrypted Assertion).
Example fix
// before
class MyInit { /* no bootstrap */ }
// after
@Configuration
class SamlInit {
@PostConstruct
void init() {
OpenSamlInitializationService.initialize();
}
} Defensive patterns
Strategy: try-catch
Validate before calling
Document doc = parseLoosely(serialized);
String ns = doc.getDocumentElement().getNamespaceURI();
if (!"urn:oasis:names:tc:SAML:2.0:protocol".equals(ns)
&& !"urn:oasis:names:tc:SAML:2.0:assertion".equals(ns)) {
throw new IllegalArgumentException("Not a SAML 2.0 element: " + doc.getDocumentElement().getTagName());
} Try / catch
try {
return template.deserialize(serialized);
} catch (Saml2Exception ex) {
log.warn("Unsupported SAML element: {}", ex.getMessage());
throw new Saml2ErrorStatusException(HttpStatus.BAD_REQUEST, ex);
} Prevention
- Always run OpenSamlInitializationService.initialize() at application startup.
- Log the raw payload (at debug) to confirm the root element before deserializing.
- Register unmarshallers for any vendor SAML extensions you accept.
- Keep OpenSAML version aligned across dependencies to avoid registry gaps.
When it happens
Trigger: Calling deserialize(String/InputStream) with XML whose document element is not a registered OpenSAML type (wrong namespace, misspelled element, non-SAML XML, or an encrypted/asserted element where a plain one is expected).
Common situations: Sending non-SAML or wrapped XML to a SAML processing endpoint; version drift where a custom/vendor extension element has no unmarshaller registered; forgetting to initialize the OpenSAML bootstrap so provider registries are empty; feeding a signed response envelope instead of the expected artifact/LogoutRequest element.
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
- Unsupported element of type " + element.getTagName()
- Unsupported element of type " + element.getTagName()
- Failed to deserialize payload
- subject_not_found
- Unable to resolve Builder for " + elementName
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/2de305dc0ad5aa5b.
Report an issue: GitHub.