spring-projects/spring-security · error · Saml2Exception

Unsupported element of type

Error message

Unsupported element of type 

What it means

The metadata-package copy of OpenSaml5Template.deserialize(): after parsing the XML it looks up an Unmarshaller for the document's root element and throws Saml2Exception when OpenSAML has no unmarshaller registered for that element type — the payload's root element is not a known OpenSAML XML type.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/metadata/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 metadata URL actually returns EntitiesDescriptor/EntityDescriptor XML — log the root tag on failure.
  2. Initialize OpenSAML default providers (OpenSamlInitializationService.initialize()) before deserializing.
  3. Add the OpenSAML module for any extension namespaces present in the metadata document.
  4. Fetch metadata over a trusted endpoint and check Content-Type/first bytes before deserializing.

Example fix

// before
EntityDescriptor ed = template.deserialize(fetch(metadataUrl));
// Saml2Exception: Unsupported element of type html (proxy returned error page)
// after
String body = fetch(metadataUrl);
if (!body.contains("EntityDescriptor")) {
    throw new Saml2Exception("Metadata endpoint returned non-SAML content");
}
EntityDescriptor ed = template.deserialize(body);
Defensive patterns

Strategy: validation

Validate before calling

String body = fetch(metadataUrl);
if (!body.trim().startsWith("<") || !body.contains("EntityDescriptor") && !body.contains("EntitiesDescriptor")) {
    throw new IllegalStateException("Metadata endpoint returned non-SAML content");
}

Type guard

static boolean isKnownSamlElement(Element root) {
    return XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(root) != null;
}

Try / catch

try {
    EntityDescriptor ed = template.deserialize(body);
} catch (Saml2Exception ex) {
    throw new Saml2Exception("Metadata root element unsupported: check endpoint output and OpenSAML modules", ex);
}

Prevention

When it happens

Trigger: Calling OpenSaml5Template.deserialize(String) on metadata/other XML whose root element namespace or name is not registered with OpenSAML — non-SAML XML (HTML error pages), unregistered extension namespaces, or deserializing before OpenSAML providers are initialized.

Common situations: A metadata endpoint behind a proxy returns an HTML error or login page; metadata extensions from namespaces whose OpenSAML module is missing; deserialize called at startup before OpenSAML initialization.

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