spring-projects/spring-security · error · Saml2Exception
Unable to resolve Builder for
Error message
Unable to resolve Builder for
What it means
This is the metadata-package copy of OpenSaml5Template.build(): it looks up an XMLObjectBuilder for the given QName in OpenSAML's registry and throws Saml2Exception when none is registered, meaning OpenSAML cannot construct the requested element type because providers were not initialized or the element is unknown to the registry.
Source
Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/metadata/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
- Initialize OpenSAML default providers before building (OpenSamlInitializationService.initialize() or Spring Security's bootstrap).
- Use the element's DEFAULT_ELEMENT_NAME constant instead of a hand-built QName.
- Add the OpenSAML module providing the element (opensaml-saml-api/impl, opensaml-saml-ext, etc.).
- For custom elements, register a builder via XMLObjectProviderRegistry.registerObjectProvider(...).
Example fix
// before
template.build(new QName("urn:oasis:names:tc:SAML:2.0:metadata", "EntityDescriptor")); // wrong ns -> no builder
// after
template.build(EntityDescriptor.DEFAULT_ELEMENT_NAME); Defensive patterns
Strategy: try-catch
Validate before calling
OpenSamlInitializationService.initialize();
if (XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(elementName) == null) {
throw new IllegalStateException("No OpenSAML builder registered for " + elementName);
} Type guard
static boolean hasBuilder(QName elementName) {
return XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(elementName) != null;
} Try / catch
try {
T obj = template.build(elementName);
} catch (Saml2Exception ex) {
throw new IllegalStateException("OpenSAML builder missing for " + elementName
+ "; initialize providers and check module dependencies", ex);
} Prevention
- Run OpenSamlInitializationService.initialize() at startup in every app using OpenSAML.
- Use DEFAULT_ELEMENT_NAME constants for metadata elements (EntityDescriptor, EntitiesDescriptor).
- Add opensaml modules for any metadata extensions you consume.
- Health-check builder availability for all elements you build.
When it happens
Trigger: Calling OpenSaml5Template.build(QName) for a metadata (or other) element with no registered builder — OpenSAML bootstrap not run, wrong QName namespace/local part, or an extension element (e.g. entity attributes) from a module that is not on the classpath.
Common situations: Generating SAML metadata before OpenSamlInitializationService.initialize() registered default providers; building EntityDescriptor sub-elements from extension namespaces without the corresponding OpenSAML dependency; hand-built QName literals with typo'd namespace URIs.
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
- Unable to resolve Builder for " + elementName
- Unsupported element of type
- Failed to deserialize payload
- Unable to resolve Builder for
- Cannot encode certificate
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/8e3ac417425b3f22.
Report an issue: GitHub.