apereo/cas · warning
Recaptcha response/token is missing from the request
Error message
Recaptcha response/token is missing from the request
What it means
ValidateCaptchaAction logs this warning when the HTTP request contains no reCAPTCHA response token (the 'g-recaptcha-response' parameter), so there is nothing to verify. The action returns the error event, failing the CAPTCHA portion of the flow.
Solutions
- Ensure the login page renders the reCAPTCHA widget and the g-recaptcha-response field is included in the POST.
- Check browser console for JavaScript failures (blocked google.com/recaptcha scripts, CSP issues).
- If integration tests or headless clients are involved, either obtain a valid test token or bypass the captcha feature for that environment.
- Confirm the correct request parameter name is being posted for the configured validator.
Example fix
<!-- before: form missing captcha field -->
<input name="username"/>
<!-- after -->
<div class="g-recaptcha" th:attr="data-sitekey=${siteKey}"></div> Defensive patterns
Strategy: validation
Validate before calling
// before submitting the login form
grecaptcha.ready(() => grecaptcha.execute(siteKey, {action: 'login'}).then(token => {
if (!token) throw new Error('recaptcha token missing');
form.append('g-recaptcha-response', token);
})); Type guard
function hasRecaptchaToken(params: URLSearchParams): boolean {
return (params.get('g-recaptcha-response') ?? '').trim().length > 0;
} Try / catch
Event e = validateCaptchaAction.execute(requestContext);
if (CasWebflowConstants.TRANSITION_ID_ERROR.equals(e.getId())) {
LOGGER.warn("CAPTCHA validation error; prompting user to retry");
modelAndView.setViewName("captcha-retry");
} Prevention
- Verify the reCAPTCHA widget renders and submits its token with the login form.
- Check CSP allows scripts from google.com/recaptcha and gstatic.com.
- For headless/test environments, disable the captcha feature instead of stubbing tokens.
- Monitor the missing-token warning to detect clients bypassing the UI.
When it happens
Trigger: doExecuteInternal calls captchaValidator.getRecaptchaResponse(request) which returns blank because the browser/client did not submit the g-recaptcha-response parameter (widget not rendered, JS disabled, form field missing, or token already consumed).
Common situations: Frontend missing the reCAPTCHA widget or not wiring g-recaptcha-response into the submitted form; JavaScript errors preventing token generation; automated clients posting directly to the endpoint without a token; tokens consumed by a prior submit.
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
- No service authentication request is available at
- Recaptcha score received is less than the threshold score…
- No username parameter is provided
- No surrogate identifier was selected or provided
- Missing web authn token from the request
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/6e055cd5ffe2cd3c.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-captcha-core/src/main/java/org/apereo/cas/web/flow/ValidateCaptchaAction.java:40
@Slf4j
@RequiredArgsConstructor
public class ValidateCaptchaAction extends BaseCasWebflowAction {
private final CaptchaValidator captchaValidator;
private final CaptchaActivationStrategy captchaActivationStrategy;
@Override
protected @Nullable Event doExecuteInternal(final RequestContext requestContext) {
if (captchaActivationStrategy.shouldActivate(requestContext, captchaValidator.getRecaptchaProperties()).isEmpty()) {
LOGGER.debug("Recaptcha is not set to activate for the current request");
return null;
}
val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(requestContext);
val userAgent = WebUtils.getHttpServletRequestUserAgentFromRequestContext(requestContext);
val gRecaptchaResponse = captchaValidator.getRecaptchaResponse(request);
if (StringUtils.isBlank(gRecaptchaResponse)) {
LOGGER.warn("Recaptcha response/token is missing from the request");
return getError(requestContext);
}
val result = captchaValidator.validate(gRecaptchaResponse, userAgent);
if (result) {
LOGGER.debug("Recaptcha has successfully validated the request");
return null;
}
return getError(requestContext);
}
private Event getError(final RequestContext requestContext) {
WebUtils.addErrorMessageToContext(requestContext, CasWebflowConstants.TRANSITION_ID_CAPTCHA_ERROR,
CasWebflowConstants.TRANSITION_ID_CAPTCHA_ERROR);
return getEventFactorySupport().event(this, CasWebflowConstants.TRANSITION_ID_CAPTCHA_ERROR);
}
}
View on GitHub (pinned to e7288fc434)