spring-projects/spring-security · error · Saml2Exception

Unsupported element of type

Error message

Unsupported element of type 

What it means

Same family as error 581, in the logout OpenSaml5Template: deserialize() throws this Saml2Exception when OpenSAML's UnmarshallerFactory has no unmarshaller for the parsed document's root element, so the logout XML cannot be converted to an XMLObject. The root element's tag name is included in the message.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/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. Check the tag name in the message and confirm the payload's root is the expected SAML protocol element with correct namespace (e.g. saml2p:LogoutRequest/LogoutResponse).
  2. Run OpenSamlInitializationService.initialize() so default unmarshallers are registered.
  3. Validate the raw payload before deserializing (well-formed XML, correct namespaces).
  4. Ensure only OpenSAML 5 jars are on the classpath.

Example fix

// before
String body = errorPageFromIdp; // not SAML
LogoutResponse lr = template.deserialize(body);

// after
OpenSamlInitializationService.initialize();
Assert.isTrue(body.contains("urn:oasis:names:tc:SAML:2.0:protocol"), "payload is not a SAML protocol document");
LogoutResponse lr = template.deserialize(body);
Defensive patterns

Strategy: validation

Validate before calling

if (!serialized.contains("urn:oasis:names:tc:SAML:2.0:protocol")) {
    throw new IllegalArgumentException("Payload root is not a SAML protocol element");
}

Try / catch

try { return template.deserialize(serialized); } catch (Saml2Exception ex) { log.warn("Unsupported logout element: {}", ex.getMessage()); throw new InvalidSamlPayloadException(ex); }

Prevention

When it happens

Trigger: Calling logout OpenSaml5Template.deserialize(String) where the root element has no registered unmarshaller — e.g. the payload's root is not a SAML element.

Common situations: Deserializing a SLO message whose root was rewritten or stripped of its namespace by a gateway; feeding HTML/plain-text error bodies; uninitialized OpenSAML registry; wrong document passed (SAML Response instead of LogoutResponse).

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/8d3ea3be24a3b694. Report an issue: GitHub.