apereo/cas · error · UnauthorizedAuthenticationException
Unable to determine the [WA] parameter
Error message
Unable to determine the [WA] parameter
What it means
WS-Federation requests must carry a `wa` (requested action) query parameter such as wsignin1.0 or wsignout1.0. WSFederationValidateRequestController.handleFederationRequest parses the request and throws UnauthorizedAuthenticationException when `wa` is blank, since it cannot dispatch to sign-in or sign-out handling without an action.
Solutions
- Ensure the relying party includes `wa=wsignin1.0` (or `wa=wsignout1.0` / `wsignoutcleanup1.0`) in the URL/POST to the CAS WS-Federation endpoint.
- Verify the full WS-Fed parameter set (wa, wtrealm, wctx, wreply) is present and that any proxy in front of CAS preserves the query string or form body.
- Test with a canonical URL like /cas/ws-idp/federation?wa=wsignin1.0&wtrealm=<realm>&wreply=<url> to confirm the endpoint itself is fine.
- If your RP framework omits `wa` on sign-out cleanup requests, configure it to send wsignoutcleanup1.0 explicitly.
Example fix
// before (RP-generated redirect, missing wa)
response.sendRedirect("https://cas.example.org/cas/ws-idp/federation?wtrealm=myRealm");
// after
response.sendRedirect("https://cas.example.org/cas/ws-idp/federation?wa=wsignin1.0&wtrealm=myRealm&wreply=https%3A%2F%2Fapp.example.org%2Fcallback"); Defensive patterns
Strategy: validation
Validate before calling
// Before redirecting to the CAS WS-Fed endpoint from an RP:
if (!request.getParameterMap().containsKey("wa") || request.getParameter("wa").isBlank()) {
throw new IllegalArgumentException("wa parameter is required (e.g. wsignin1.0)");
} Prevention
- Always build WS-Fed sign-in messages via a library or constant for wa=wsignin1.0, never by hand.
- Test reverse proxies preserve query strings and form bodies for the federation endpoint.
- Include wtrealm/wctx/wreply alongside wa in every message.
When it happens
Trigger: A client hits the WS-Federation /federation endpoint (GET/POST handled by handleFederationRequest) and `WSFederationRequest.of(request).wa()` resolves to null or empty string — i.e. the `wa` parameter is absent, empty, or not propagated through a proxy.
Common situations: RP-generated sign-in messages missing the wa=wsignin1.0 parameter; reverse proxies or gateways stripping query strings; hand-built deep links to the CAS WS-Fed endpoint copied without full parameters; metadata/claim-rules rewriting the redirect URL and dropping parameters.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- The authentication request is not recognized
- Missing parameter wresult
- No state could be found to determine session state
- Credential attributes do not include an attribute for
- Failed to load configuration metadata
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/f3fc5a5c6863ea3f.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/WSFederationValidateRequestController.java:49
public WSFederationValidateRequestController(final WSFederationRequestConfigurationContext ctx) {
super(ctx);
}
/**
* Handle federation request.
*
* @param response the response
* @param request the request
* @throws Exception the exception
*/
@GetMapping(path = WSFederationConstants.ENDPOINT_FEDERATION_REQUEST)
@Operation(summary = "Handle federation request")
public void handleFederationRequest(final HttpServletResponse response,
final HttpServletRequest request) throws Exception {
val fedRequest = WSFederationRequest.of(request);
val wa = fedRequest.wa();
if (StringUtils.isBlank(wa)) {
throw new UnauthorizedAuthenticationException("Unable to determine the [WA] parameter", new HashMap<>());
}
switch (wa.toLowerCase(Locale.ENGLISH)) {
case WSFederationConstants.WSIGNOUT10, WSFederationConstants.WSIGNOUT_CLEANUP10 -> handleLogoutRequest(fedRequest, request, response);
case WSFederationConstants.WSIGNIN10 -> handleInitialAuthenticationRequest(fedRequest, response, request);
default -> throw new UnauthorizedAuthenticationException("The authentication request is not recognized", new HashMap<>());
}
}
protected void handleLogoutRequest(final WSFederationRequest fedRequest, final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
val logoutUrl = FunctionUtils.doIf(StringUtils.isNotBlank(fedRequest.wreply()),
() -> {
val service = createService(fedRequest);
val registeredService = getWsFederationRegisteredService(service);
LOGGER.debug("Invoking logout operation for request [{}], redirecting next to [{}] matched against [{}]",
fedRequest, fedRequest.wreply(), registeredService);View on GitHub (pinned to e7288fc434)