spring-projects/spring-security · error · Saml2Exception

Unable to resolve Builder for

Error message

Unable to resolve Builder for 

What it means

OpenSaml5Template.build() looks up an OpenSAML XMLObjectBuilder for the given QName via the global XMLObjectProviderRegistry. When no builder is registered for that element name, the template cannot construct the XMLObject and throws this Saml2Exception. This almost always means the OpenSAML object provider initialization did not run or the element is not a known SAML element.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java:132

import org.springframework.security.saml2.core.Saml2ParameterNames;
import org.springframework.security.saml2.core.Saml2X509Credential;
import org.springframework.util.Assert;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;

/**
 * For internal use only. Subject to breaking changes at any time.
 */
@NullMarked
final class OpenSaml5Template implements OpenSamlOperations {

	private static final Log logger = LogFactory.getLog(OpenSaml5Template.class);

	@Override
	public <T extends XMLObject> T build(QName elementName) {
		XMLObjectBuilder<?> builder = XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(elementName);
		if (builder == null) {
			throw new Saml2Exception("Unable to resolve Builder for " + elementName);
		}
		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);

View on GitHub (pinned to 96852e8860)

Solutions

  1. Ensure OpenSAML is initialized before building — add opensaml-saml-api/impl to the classpath and let org.springframework.security.saml2 (OpenSamlInitializationService / InitializationService) register the default providers, or call InitializationService.initialize() yourself
  2. Verify the QName's namespace URI and localPart exactly match the SAML element (e.g. Response.DEFAULT_ELEMENT_NAME), not a hand-typed string
  3. Check for conflicting opensaml jar versions on the classpath that may break provider registration
  4. If building a custom element, register an XMLObjectBuilder for it with the BuilderRegistry before calling build

Example fix

// before
XMLObject obj = template.build(new QName("urn:oasis:names:tc:SAML:2.0:protocol", "Resposne"));
// after
XMLObject obj = template.build(Response.DEFAULT_ELEMENT_NAME);
Defensive patterns

Strategy: validation

Validate before calling

InitializationService.initialize(); // once at startup, before any build()
if (XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(elementName) == null) {
    throw new IllegalStateException("No OpenSAML builder for " + elementName);
}

Type guard

boolean canBuild(QName name) {
    return XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(name) != null;
}

Try / catch

try {
    T obj = template.build(elementName);
} catch (Saml2Exception ex) {
    throw new IllegalStateException("Unknown/unregistered element: " + elementName, ex);
}

Prevention

When it happens

Trigger: Calling OpenSaml5Template.build(QName) with a QName whose builder is absent from XMLObjectProviderRegistrySupport — e.g. a typo'd namespace URI or localPart, or building before OpenSAML's InitializationService has registered the standard SAML providers (typically done by OpenSamlInitializationService in this library).

Common situations: Using a custom/unknown element QName; constructing the template manually without triggering OpenSAML bootstrap initialization (no class from opensaml-saml-api touched first); mixing OpenSAML 4/5 jars so registry registration fails; building extension elements from a profile whose providers were never registered.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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