apereo/cas · warning
No recipient is provided with a valid email/phone
Error message
No recipient is provided with a valid email/phone
What it means
SendPasswordResetInstructionsAction (webflow action) looks up the request's email(s) and phone for the password-reset query; when neither yields a recipient it logs this warn and returns the invalid-contact event, sending the user back to the prompt screen instead of generating a reset link.
Solutions
- Ensure the user record has a valid mail or sms attribute matching cas.authn.pm.reset.mail/sms.attributeName
- Enable debug logging on org.apereo.cas.pm to see which lookup (email vs phone) failed and why
- Validate the username submitted on the form corresponds to an existing directory entry
- Check the underlying service is not the no-op PM service (see no-op warn)
Example fix
// before — webflow returns 'invalidContact' because mail attribute is empty // after — set in directory: mail: user@example.com // action then proceeds and stores the PasswordManagementQuery in flow scope
Defensive patterns
Strategy: validation
Validate before calling
// before submitting the reset form, verify a contact exists
var query = PasswordManagementQuery.builder().username(username).build();
boolean reachable = !pmService.findEmails(query).isEmpty() || StringUtils.isNotBlank(pmService.findPhone(query));
if (!reachable) { showInvalidContactMessage(); } Prevention
- Pre-validate usernames and contact attributes on the reset form
- Check CAS logs for the upstream findEmails/findAttribute warnings to pinpoint the failure
- Keep PM mail/sms attribute configuration in the environment checklist
When it happens
Trigger: doExecuteInternal runs with locatePasswordResetRequestEmail returning an empty collection and locatePasswordResetRequestPhone returning nothing — the PM service found no valid contact for the username entered on the reset form.
Common situations: Typo'd username on the reset form mapping to an entry without contact attributes; mail attribute fails email validation; LDAP bind/search misconfigured so lookups return nothing; testing with users that have no mail/mobile populated.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- No recipient is provided with a valid email/phone for
- No registered devices for multifactor authentication could…
- Email registration is not enabled for
- State [ : : ] does not have a matching transition for
- Deserialization error
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/32e2a98a81e75b35.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/SendPasswordResetInstructionsAction.java:126
actionResolverName = AuditActionResolvers.REQUEST_CHANGE_PASSWORD_ACTION_RESOLVER,
resourceResolverName = AuditResourceResolvers.REQUEST_CHANGE_PASSWORD_RESOURCE_RESOLVER)
@Override
protected @Nullable Event doExecuteInternal(final RequestContext requestContext) throws Throwable {
communicationsManager.validate();
if (!communicationsManager.isMailSenderDefined() && !communicationsManager.isSmsSenderDefined()) {
return getErrorEvent("contact.failed", "Unable to send email as no mail sender is defined", requestContext);
}
val query = buildPasswordManagementQuery(requestContext);
if (StringUtils.isBlank(query.getUsername())) {
return getErrorEvent("username.required", "No username is provided", requestContext);
}
val emails = locatePasswordResetRequestEmail(requestContext, query);
val phones = locatePasswordResetRequestPhone(requestContext, query);
if (emails.isEmpty() && phones.isEmpty()) {
LOGGER.warn("No recipient is provided with a valid email/phone");
return getInvalidContactEvent(requestContext);
}
WebUtils.putPasswordManagementQuery(requestContext, query);
if (doesPasswordResetRequireMultifactorAuthentication(requestContext)
&& !hasPrincipalRegisteredMultifactorAuthenticationDevice(requestContext)) {
LOGGER.warn("No registered devices for multifactor authentication could be found for [{}]", query.getUsername());
WebUtils.addErrorMessageToContext(requestContext, "screen.mfaDenied.message");
return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_DENY);
}
val service = WebUtils.getService(requestContext);
val url = buildPasswordResetUrl(query.getUsername(), service);
if (url != null) {
val sendEmail = sendPasswordResetEmailToAccount(query.getUsername(), emails, url, requestContext);
val sendSms = sendPasswordResetSmsToAccount(requestContext, phones, url);
if (sendEmail.isSuccess() || sendSms) {
return success(url);
}
} else {View on GitHub (pinned to e7288fc434)