{"record":{"id":"7a808d7e02a9a463","repo":"spring-projects/spring-security","slug":"unable-to-determine-message-binding-from-request","errorCode":null,"errorMessage":"Unable to determine message binding from request.","messagePattern":"Unable to determine message binding from request\\.","errorType":"exception","errorClass":"Saml2Exception","httpStatus":500,"severity":"error","filePath":"saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2MessageBindingUtils.java","lineNumber":44,"sourceCode":" * Utility methods for working with {@link Saml2MessageBinding}\n *\n * For internal use only.\n *\n * @since 5.8\n */\nfinal class Saml2MessageBindingUtils {\n\n\tprivate Saml2MessageBindingUtils() {\n\t}\n\n\tstatic Saml2MessageBinding resolveBinding(HttpServletRequest request) {\n\t\tif (isHttpPostBinding(request)) {\n\t\t\treturn Saml2MessageBinding.POST;\n\t\t}\n\t\telse if (isHttpRedirectBinding(request)) {\n\t\t\treturn Saml2MessageBinding.REDIRECT;\n\t\t}\n\t\tthrow new Saml2Exception(\"Unable to determine message binding from request.\");\n\t}\n\n\tprivate static boolean isSamlRequestResponse(HttpServletRequest request) {\n\t\treturn (request.getParameter(Saml2ParameterNames.SAML_REQUEST) != null\n\t\t\t\t|| request.getParameter(Saml2ParameterNames.SAML_RESPONSE) != null);\n\t}\n\n\tstatic boolean isHttpRedirectBinding(HttpServletRequest request) {\n\t\treturn \"GET\".equalsIgnoreCase(request.getMethod()) && isSamlRequestResponse(request);\n\t}\n\n\tstatic boolean isHttpPostBinding(HttpServletRequest request) {\n\t\treturn \"POST\".equalsIgnoreCase(request.getMethod()) && isSamlRequestResponse(request);\n\t}\n\n}\n","sourceCodeStart":26,"sourceCodeEnd":61,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/Saml2MessageBindingUtils.java#L26-L61","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Configure the identity provider to send Single Logout messages via HTTP-POST or HTTP-Redirect binding only.","Verify the SLO endpoint URL in the IdP metadata matches the servlet path your app exposes and that the SAMLRequest/SAMLResponse parameter is present.","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."],"exampleFix":"// before\nSaml2MessageBinding binding = Saml2MessageBindingUtils.resolveBinding(request);\n// after\nif (request.getParameter(Saml2ParameterNames.SAML_REQUEST) == null\n        && request.getParameter(Saml2ParameterNames.SAML_RESPONSE) == null) {\n    response.sendError(HttpServletResponse.SC_BAD_REQUEST);\n    return;\n}\nSaml2MessageBinding binding = Saml2MessageBindingUtils.resolveBinding(request);","handlingStrategy":"validation","validationCode":"boolean isSamlMessage = request.getParameter(Saml2ParameterNames.SAML_REQUEST) != null\n        || request.getParameter(Saml2ParameterNames.SAML_RESPONSE) != null;\nif (!isSamlMessage || !(Saml2MessageBindingUtils.isHttpPostBinding(request)\n        || Saml2MessageBindingUtils.isHttpRedirectBinding(request))) {\n    response.sendError(HttpServletResponse.SC_BAD_REQUEST, \"Unsupported SAML binding\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    Saml2MessageBinding binding = Saml2MessageBindingUtils.resolveBinding(request);\n} catch (Saml2Exception ex) {\n    response.sendError(HttpServletResponse.SC_BAD_REQUEST, \"Unsupported SAML binding\");\n}","preventionTips":["Restrict the IdP's SLO endpoint bindings to HTTP-POST and HTTP-Redirect in its metadata.","Test the full logout round-trip against your IdP in CI.","Verify SLO endpoint URLs match your filter's request matcher path."],"tags":["saml2","spring-security","http-binding","request-parsing"],"backgroundTag":"invalid-enum-value","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}