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

  1. 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.
  2. Call OpenSamlInitializationService.initialize() before deserializing so default unmarshallers are registered.
  3. 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.
  4. 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

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


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