spring-projects/spring-security · error · Saml2Exception
Unable to resolve Builder for
Error message
Unable to resolve Builder for
What it means
Identical to error 580 but in the logout package's OpenSaml5Template: build() throws this Saml2Exception when OpenSAML's XMLObjectBuilderFactory has no builder registered for the given QName, so the requested SAML element cannot be constructed.
Source
Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/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 via OpenSamlInitializationService.initialize() before calling build().
- Use canonical constants like LogoutRequest.DEFAULT_ELEMENT_NAME rather than manually constructed QNames.
- Remove conflicting OpenSAML versions from the classpath and confirm providers load at startup.
- For custom elements, register an XMLObjectBuilder in the XMLObjectProviderRegistry.
Example fix
// before
QName q = new QName("LogoutRequest");
LogoutRequest req = template.build(q);
// after
OpenSamlInitializationService.initialize();
LogoutRequest req = template.build(LogoutRequest.DEFAULT_ELEMENT_NAME); Defensive patterns
Strategy: validation
Validate before calling
OpenSamlInitializationService.initialize();
if (XMLObjectProviderRegistrySupport.getBuilderFactory().getBuilder(elementName) == null) {
throw new IllegalStateException("No OpenSAML builder for " + elementName);
} Try / catch
try { T obj = template.build(elementName); } catch (Saml2Exception ex) { log.error("Logout template cannot build {}", elementName, ex); throw ex; } Prevention
- Initialize OpenSAML registry at startup
- Use LogoutRequest.DEFAULT_ELEMENT_NAME / LogoutResponse.DEFAULT_ELEMENT_NAME constants
- Avoid duplicate OpenSAML 4/5 dependencies
When it happens
Trigger: Calling the logout OpenSaml5Template.build(QName) with an element name for which getBuilderFactory().getBuilder(elementName) returns null (unregistered/unknown element).
Common situations: Building LogoutRequest/LogoutResponse with a hand-crafted QName instead of the *.DEFAULT_ELEMENT_NAME constants; OpenSAML registry not initialized; duplicate OpenSAML 4/5 jars; using extension elements whose providers were never registered.
Related errors
- Unable to resolve Builder for
- Unsupported element of type
- Failed to deserialize payload
- Unsupported object of type:
- Spring Security does not support OpenSAML {Version.getVersio
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/2589ec38620cfd02.
Report an issue: GitHub.