{"record":{"id":"32e2a98a81e75b35","repo":"apereo/cas","slug":"no-recipient-is-provided-with-a-valid-email-phone-32e2a9","errorCode":null,"errorMessage":"No recipient is provided with a valid email/phone","messagePattern":"No recipient is provided with a valid email/phone","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/SendPasswordResetInstructionsAction.java","lineNumber":126,"sourceCode":"        actionResolverName = AuditActionResolvers.REQUEST_CHANGE_PASSWORD_ACTION_RESOLVER,\n        resourceResolverName = AuditResourceResolvers.REQUEST_CHANGE_PASSWORD_RESOURCE_RESOLVER)\n    @Override\n    protected @Nullable Event doExecuteInternal(final RequestContext requestContext) throws Throwable {\n        communicationsManager.validate();\n        if (!communicationsManager.isMailSenderDefined() && !communicationsManager.isSmsSenderDefined()) {\n            return getErrorEvent(\"contact.failed\", \"Unable to send email as no mail sender is defined\", requestContext);\n        }\n\n        val query = buildPasswordManagementQuery(requestContext);\n        if (StringUtils.isBlank(query.getUsername())) {\n            return getErrorEvent(\"username.required\", \"No username is provided\", requestContext);\n        }\n\n        val emails = locatePasswordResetRequestEmail(requestContext, query);\n        val phones = locatePasswordResetRequestPhone(requestContext, query);\n\n        if (emails.isEmpty() && phones.isEmpty()) {\n            LOGGER.warn(\"No recipient is provided with a valid email/phone\");\n            return getInvalidContactEvent(requestContext);\n        }\n        WebUtils.putPasswordManagementQuery(requestContext, query);\n        if (doesPasswordResetRequireMultifactorAuthentication(requestContext)\n            && !hasPrincipalRegisteredMultifactorAuthenticationDevice(requestContext)) {\n            LOGGER.warn(\"No registered devices for multifactor authentication could be found for [{}]\", query.getUsername());\n            WebUtils.addErrorMessageToContext(requestContext, \"screen.mfaDenied.message\");\n            return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_DENY);\n        }\n        val service = WebUtils.getService(requestContext);\n        val url = buildPasswordResetUrl(query.getUsername(), service);\n        if (url != null) {\n            val sendEmail = sendPasswordResetEmailToAccount(query.getUsername(), emails, url, requestContext);\n            val sendSms = sendPasswordResetSmsToAccount(requestContext, phones, url);\n            if (sendEmail.isSuccess() || sendSms) {\n                return success(url);\n            }\n        } else {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/SendPasswordResetInstructionsAction.java#L108-L144","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before — webflow returns 'invalidContact' because mail attribute is empty\n// after — set in directory: mail: user@example.com\n// action then proceeds and stores the PasswordManagementQuery in flow scope","handlingStrategy":"validation","validationCode":"// before submitting the reset form, verify a contact exists\nvar query = PasswordManagementQuery.builder().username(username).build();\nboolean reachable = !pmService.findEmails(query).isEmpty() || StringUtils.isNotBlank(pmService.findPhone(query));\nif (!reachable) { showInvalidContactMessage(); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["webflow","password-reset","email","missing-attribute"],"backgroundTag":"empty-result-set","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}