spring-projects/spring-security · error · Saml2AuthenticationException
invalid_request
invalid_request
Error message
Logout request used invalid binding
What it means
Saml2LogoutRequestFilter.validateLogoutRequest resolves the binding of the incoming logout request (from the request parameters/transport) and checks it is among the registration's getSingleLogoutServiceBindings(). If the used binding (e.g. REDIRECT) is not in the configured set (e.g. only POST), it throws Saml2AuthenticationException with code invalid_request and message 'Logout request used invalid binding'.
Source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2LogoutRequestFilter.java:193
*/
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
this.securityContextHolderStrategy = securityContextHolderStrategy;
}
private void validateLogoutRequest(HttpServletRequest request, Saml2LogoutRequestValidatorParameters parameters) {
RelyingPartyRegistration registration = parameters.getRelyingPartyRegistration();
if (registration.getSingleLogoutServiceLocation() == null) {
this.logger.trace(
"Did not process logout request since RelyingPartyRegistration has not been configured with a logout request endpoint");
throw new Saml2AuthenticationException(new Saml2Error(Saml2ErrorCodes.INVALID_DESTINATION,
"RelyingPartyRegistration has not been configured with a logout request endpoint"));
}
Saml2MessageBinding saml2MessageBinding = Saml2MessageBindingUtils.resolveBinding(request);
if (!registration.getSingleLogoutServiceBindings().contains(saml2MessageBinding)) {
this.logger.trace("Did not process logout request since used incorrect binding");
throw new Saml2AuthenticationException(
new Saml2Error(Saml2ErrorCodes.INVALID_REQUEST, "Logout request used invalid binding"));
}
Saml2LogoutValidatorResult result = this.logoutRequestValidator.validate(parameters);
if (result.hasErrors()) {
this.logger.debug(LogMessage.format("Failed to validate LogoutRequest: %s", result.getErrors()));
throw new Saml2AuthenticationException(
new Saml2Error(Saml2ErrorCodes.INVALID_REQUEST, "Failed to validate the logout request"));
}
}
private void sendLogoutResponse(HttpServletRequest request, HttpServletResponse response,
Saml2LogoutResponse logoutResponse) throws IOException {
if (logoutResponse.getBinding() == Saml2MessageBinding.REDIRECT) {
doRedirect(request, response, logoutResponse);
}
else {
doPost(request, response, logoutResponse);View on GitHub (pinned to 96852e8860)
Solutions
- Align singleLogoutServiceBinding(s) in the registration with what the IDP actually sends (check IDP's SingleLogoutService Binding attribute in metadata)
- Re-import IDP metadata so bindings are picked up automatically
- Update the IDP's SLO binding setting to match the SP configuration
- Verify proxies preserve both query parameters (Redirect binding) and form bodies (POST binding)
Example fix
// before (only POST configured, IDP sends Redirect)
.singleLogoutServiceLocation("https://idp/slo")
.singleLogoutServiceBinding(Saml2MessageBinding.POST)
// after (accept the binding the IDP uses)
.singleLogoutServiceLocation("https://idp/slo")
.singleLogoutServiceBindings(b -> b.addAll(List.of(Saml2MessageBinding.POST, Saml2MessageBinding.REDIRECT))) Defensive patterns
Strategy: validation
Validate before calling
Saml2MessageBinding inbound = Saml2MessageBindingUtils.resolveBinding(request);
if (!registration.getSingleLogoutServiceBindings().contains(inbound)) {
log.warn("SLO binding " + inbound + " not enabled for registration");
} Try / catch
try { /* saml2Logout configuration */ } catch (Saml2AuthenticationException ex) {
if ("invalid_request".equals(ex.getSaml2Error().getErrorCode())) {
log.warn("SLO binding mismatch", ex);
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
} else { throw ex; }
} Prevention
- Copy the binding(s) from IDP metadata exactly; enable both POST and REDIRECT if in doubt
- Re-import metadata after the IDP changes its SLO binding
- Test SLO through the full proxy chain
When it happens
Trigger: The IDP sends the LogoutRequest via a binding (Redirect or POST) not listed in the RelyingPartyRegistration's singleLogoutServiceBindings, or the SP config lists the wrong binding(s).
Common situations: IDP metadata advertises Redirect binding but the SP registration was hand-configured with POST only (or vice versa); IDP config changed binding after metadata import; reverse proxy stripping query parameters making Redirect-bound messages look malformed.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Failed to decode SAMLResponse
- SAML payload exceeded maximum size of
- relying_party_registration_not_found
- invalid_destination
- relying_party_registration_not_found
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/75cdebf1a616e49c.
Report an issue: GitHub.