spring-projects/spring-security · error · Saml2Exception

Unable to determine message binding from request.

Error message

Unable to determine message binding from request.

What it means

Saml2MessageBindingUtils.resolveBinding inspects the HttpServletRequest to decide whether the SAML message uses HTTP-POST or HTTP-Redirect binding. If neither binding's characteristic parameters are present (e.g. no SAMLRequest/SAMLResponse parameter arranged as POST or Redirect expects), it throws Saml2Exception because the library cannot know how to serialize or deserialize the message.

Solutions

  1. Configure the identity provider to send Single Logout messages via HTTP-POST or HTTP-Redirect binding only.
  2. Verify the SLO endpoint URL in the IdP metadata matches the servlet path your app exposes and that the SAMLRequest/SAMLResponse parameter is present.
  3. In custom code, check Saml2MessageBindingUtils.isHttpPostBinding/isHttpRedirectBinding (or the presence of the SAML parameter) before calling resolveBinding and return a 400 response when neither matches.

Example fix

// before
Saml2MessageBinding binding = Saml2MessageBindingUtils.resolveBinding(request);
// after
if (request.getParameter(Saml2ParameterNames.SAML_REQUEST) == null
        && request.getParameter(Saml2ParameterNames.SAML_RESPONSE) == null) {
    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
    return;
}
Saml2MessageBinding binding = Saml2MessageBindingUtils.resolveBinding(request);
Defensive patterns

Strategy: validation

Validate before calling

boolean isSamlMessage = request.getParameter(Saml2ParameterNames.SAML_REQUEST) != null
        || request.getParameter(Saml2ParameterNames.SAML_RESPONSE) != null;
if (!isSamlMessage || !(Saml2MessageBindingUtils.isHttpPostBinding(request)
        || Saml2MessageBindingUtils.isHttpRedirectBinding(request))) {
    response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unsupported SAML binding");
    return;
}

Try / catch

try {
    Saml2MessageBinding binding = Saml2MessageBindingUtils.resolveBinding(request);
} catch (Saml2Exception ex) {
    response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unsupported SAML binding");
}

Prevention

When it happens

Trigger: Calling resolveBinding(request) with a request lacking a SAMLRequest or SAMLResponse parameter, or having one but not matching isHttpPostBinding/isHttpRedirectBinding heuristics (e.g. missing RelayState/signature algorithm params used to distinguish binding types).

Common situations: IdP sends logout message with a binding your app doesn't expect (e.g. SOAP or Artifact binding); misconfigured IdP SLO endpoint pointing at the wrong URL; a test hitting the SLO endpoint without query/form parameters; custom filter code reusing resolveBinding on a non-SAML request.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2MessageBindingUtils.java:44

 * Utility methods for working with {@link Saml2MessageBinding}
 *
 * For internal use only.
 *
 * @since 5.8
 */
final class Saml2MessageBindingUtils {

	private Saml2MessageBindingUtils() {
	}

	static Saml2MessageBinding resolveBinding(HttpServletRequest request) {
		if (isHttpPostBinding(request)) {
			return Saml2MessageBinding.POST;
		}
		else if (isHttpRedirectBinding(request)) {
			return Saml2MessageBinding.REDIRECT;
		}
		throw new Saml2Exception("Unable to determine message binding from request.");
	}

	private static boolean isSamlRequestResponse(HttpServletRequest request) {
		return (request.getParameter(Saml2ParameterNames.SAML_REQUEST) != null
				|| request.getParameter(Saml2ParameterNames.SAML_RESPONSE) != null);
	}

	static boolean isHttpRedirectBinding(HttpServletRequest request) {
		return "GET".equalsIgnoreCase(request.getMethod()) && isSamlRequestResponse(request);
	}

	static boolean isHttpPostBinding(HttpServletRequest request) {
		return "POST".equalsIgnoreCase(request.getMethod()) && isSamlRequestResponse(request);
	}

}

View on GitHub (pinned to 96852e8860)