---
title: "Password Reset Not Working in Ultimate Member"
date: 2026-08-08
modified: 2026-08-08
author: "userelements_wh8sr3"
url: "https://www.userelements.com/password-reset-not-working-in-ultimate-member/"
markdown_url: "https://www.userelements.com/password-reset-not-working-in-ultimate-member.md"
type: post
excerpt: "Password reset is one of the most common real-world Ultimate Member breakages. Official docs barely cover it because the failure […]"
categories:
  - "Ultimate Member"
---
Password reset is one of the most common real-world Ultimate Member breakages. Official docs barely cover it because the failure is rarely “UM is broken”—it’s usually page misconfiguration, email delivery, cookies, or full-page caching colliding with how WordPress reset keys work.

This guide walks the real flow in UM, then the four failure domains that cause most tickets: reset page, SMTP/email, cookies, and cache.

---

## How Ultimate Member password reset actually works

UM does not invent its own reset system. It wraps WordPress core keys and a cookie handoff, on a dedicated core page.

### Request flow (forgot password)

1. User opens the Password Reset core page (`[ultimatemember_password]`).
2. They submit username or email (`_um_password_reset=1`).
3. On `template_redirect`, UM validates, then (if allowed) queues Password Reset Email (`resetpw_email`).
4. User is always redirected to `?updated=checkemail` with:

> *If an account matching the provided details exists, we will send a password reset link…*

That message is not proof an email was sent. Unknown users and (by default) non-approved users get the same screen. No email goes out in those cases.

### Email link flow (set new password)

Reset URL shape:

{password-reset-page}?act=reset\_password&amp;hash={key}&amp;login={user\_login}

1. UM sets cookie `wp-resetpass-{COOKIEHASH}` = `login:hash`.
2. It redirects to the same page without `hash`/`login` in the URL (security: key not left in browser history).
3. It validates via WordPress `check_password_reset_key()`.
4. If valid → show set-password form (`password-change.php`).
5. On success → WordPress `reset_password()`, clear cookie, redirect to login with `?updated=password_changed`.

Users are not auto-logged in after a forgot-password reset. They must sign in with the new password.

---

## 1. Reset page problems (most common structural failure)

### What must be true

RequirementDetailCore page assignedUltimate Member → Settings → General → Pages → Password ResetOption key`core_password-reset` in `um_options`Page contentMust include `[ultimatemember_password]` (or the Password Reset block)Reachable by guestsSitewide restriction skips this page by designIf the page is missing, unpublished, wrong, or empty of the shortcode:

- “Forgot your password?” links go nowhere / wrong URL
- `{password_reset_link}` in email can be empty or point at the wrong place
- After clicking the email, validation redirects fail (`invalidkey` / blank page)

### Checklist

1. Confirm Settings → General → Pages → Password Reset points at a real published page.
2. Edit that page and confirm it contains `[ultimatemember_password]` only (no conflicting forms).
3. Open the page logged out. You should see the username/email form.
4. On multilingual sites (WPML/Polylang), confirm each language has a mapped password-reset page. A link generated in EN that lands on a DE page without the cookie/path match often shows invalid key.
5. Do not put the shortcode on a random “Contact” page and expect core redirects to find it—UM uses the assigned core page URL for emails and redirects.

### Symptom → cause

SymptomLikely causeForgot link 404 / homeCore page deleted or not assignedEmail button goes to homepageEmpty `um_get_core_page( 'password-reset' )`Form missing on pageShortcode removed; custom builder block stripped itWorks in one language onlyMultilingual page mapping incompleteFix: Reassign or recreate the core page (UM’s “Install Core Pages” notice if offered), put the shortcode back, retest logged out.

---

## 2. SMTP / email (the “I got checkemail but nothing arrived” case)

UM does not ship SMTP. Path is:

password\_reset() → um\_dispatch\_email → UM()-&gt;mail()-&gt;send() → wp\_mail()

If `wp_mail()` fails (or never runs), users still see the success-style checkemail screen.

### Silent “no email” causes inside UM

1. Password Reset Email is disabled  
    Settings → Emails → Password Reset Email must be On (`resetpw_email_on`).
2. User is not Approved (default)  
    Setting Only allow approved users to reset password (`only_approved_user_reset_password`, default on) means awaiting email / pending / inactive users get checkemail but no mail.
3. Wrong / non-existent username or email  
    Deliberate anti-enumeration: same checkemail UI, no mail.
4. Action Scheduler delay/failure  
    If Enable Action Scheduler for email sending is on, mail is queued. Stuck/failed jobs = delayed or never-sent mail. Check pending/failed AS actions for `um_dispatch_email`.
5. Broken `{password_reset_link}`  
    Link is built when the email is queued, using the core password-reset page. If that page URL is empty, the button is useless even if the email arrives.

### SMTP / deliverability (outside UM)

Typical stack failures:

- No SMTP plugin; host blocks `phpmailer` / port 25
- From address not aligned with authenticated SMTP domain (`mail_from` / `mail_from_addr` in UM Emails settings)
- SPF/DKIM/DMARC fail → spam folder or soft bounce
- Security plugins blocking outbound mail
- Shared hosting rate limits

### How to verify email actually fires

1. Temporarily enable a mail logger (e.g. WP Mail Logging) or your SMTP plugin’s log.
2. Reset with a known approved account and correct email.
3. Confirm a `resetpw_email` (subject default: “Reset your password”) was attempted.
4. If logged as sent but not received → DNS/spam/provider.
5. If never logged → UM setting, approval status, AS queue, or code killing send via `um_disable_email_notification_sending`.

### Rate limit that looks like “email broken”

Settings → Access → Other → Reset Password:

- Limit enabled by default
- Default max attempts: 3 (`password_rst_attempts` user meta)

After the limit:

> *You have reached the limit for requesting password change…*

Clear by successful reset, successful login (`wp_login` clears attempts), or manually clearing that user meta. Admins can be excluded via the admin limit-disable option when present.

---

## 3. Cookies (invalid key right after opening a “good” email)

This is the most confusing UX: email looks correct, user clicks once, and UM says:

- *Your password reset link appears to be invalid…* (`updated=invalidkey`)
- or *…has expired…* (`updated=expiredkey`)

### Cookie handoff (by design)

UM mirrors WordPress:

1. Link contains `hash` + `login`.
2. First hit sets `wp-resetpass-{COOKIEHASH}` and strips those query args.
3. Second request must send that cookie back; otherwise key check fails → `invalidkey`.

So anything that blocks or mismatches cookies breaks reset even when the key in the email is valid.

### Common cookie breakers

CauseWhat happensBrowser blocks third-party / all cookiesCookie never stored → invalidkeyITP / strict privacy / “Prevent cross-site tracking”SameOpening link in a different browser/app than email client’s in-app browserCookie set in WebView A, form opens in Browser BHTTP vs HTTPS mismatch / wrong domain (`www` vs bare)Cookie path/domain doesn’t match next requestCookie path from odd `REQUEST_URI`Cookie set for a path that isn’t used on the follow-up requestSecurity plugins rewriting cookies / cookie law banners delaying setRace or blocked setUser bookmarks the pre-redirect URL with hash and reuses it laterKey already consumed or cookie flow skipped incorrectlyUM calls `nocache_headers()` when setting the cookie, but that only helps the cookie-set response—not a cached HTML page in front of it (see cache section).

### Expired vs invalid

- `expiredkey`: WordPress reset key lifetime exceeded (filter `password_reset_expiration`, typically ~1 day). Or user requested a new reset (new key invalidates the old one).
- `invalidkey`: Cookie missing/mismatched, key wrong, already used, or page/cookie path broken.

### Cookie troubleshooting steps

1. Test in a clean private window with cookies allowed.
2. Click the link once; do not open it twice from the email.
3. Confirm site URL is consistent (HTTPS, canonical host) in Settings → General and UM pages.
4. Disable cookie/consent blockers briefly on that domain.
5. Avoid email “link checkers” / corporate scanners that prefetch the URL (they can consume or confuse the one-time cookie flow).
6. After one failed click, request a fresh email—don’t keep retrying the same link.

---

## 4. Cache (the silent killer of password reset)

Full-page cache is the #1 infrastructure reason reset “randomly” fails on otherwise healthy sites.

### Why cache breaks this flow

Password reset needs:

- Fresh POST handling for the request form
- A Set-Cookie + redirect on `?act=reset_password&hash=…&login=…`
- A follow-up request that sees the cookie and renders the change form
- Dynamic `?updated=` messages

If a CDN/plugin serves cached HTML for the password-reset page:

- POST may never hit PHP
- Cookie may never be set
- User may see a stale “request form” instead of the change-password form
- `invalidkey` appears even with a valid email link
- checkemail / error banners don’t update

UM only sends `nocache_headers()` when setting the reset cookie—not on every view of the page. You must exclude the page at the cache layer.

### What to exclude from cache

Always exclude (by URL and/or cookie):

1. The Password Reset core page (and all language variants)
2. Login / Register / Account core pages (related auth flows)
3. URLs containing `act=reset_password`
4. Query args: `updated`, `hash`, `login` (or better: bypass cache for the whole page)
5. Logged-in users (usually already done)
6. Cookie `wp-resetpass-*` if your cache supports cookie-based bypass

Applies to: WP Rocket, LiteSpeed, Cloudflare, NitroPack, SG Optimizer, Host cache, etc.

### Object / user cache notes

UM deletes `um_cache_userdata_{user_id}` when generating a reset URL. That is not a substitute for excluding the page from full-page cache. Don’t rely on object-cache plugins to “fix” password reset.

### Cache verification

1. Purge all caches.
2. Exclude password-reset page permanently.
3. Request reset → confirm email.
4. Click link once → you should land on set new password fields (not the username request form).
5. If you still see the request form with `invalidkey`, cache or cookies are still interfering.

---

## Symptom decision tree

User submits reset form

│

├─ Error: empty username/email → fill the field

├─ Error: request limit → clear attempts / wait / login once

└─ Sees checkemail

│

├─ No email in logger → email Off / not approved / wrong user / AS / wp\_mail

├─ Email in logger, not in inbox → SMTP/DNS/spam

└─ Email received

│

├─ Link host wrong / 404 → fix core Password Reset page

├─ invalidkey immediately → cookies / cache / path / prefetch

├─ expiredkey → new request; don’t reuse old link

└─ Change form shows

│

├─ Strong password / mismatch errors → fix password rules

└─ Success → login with new password (no auto-login)

---

## Settings map (where to look in admin)

Pages

- Ultimate Member → Settings → General → Pages → Password Reset

Access / limits

- Settings → Access → Other → Reset Password 
    - Enable limit / max attempts
    - Only approved users can reset (default on)

Emails

- Settings → Emails → Password Reset Email (and From name/address)
- Optional: Action Scheduler email sending
- Also: Password Changed Email after success

Appearance / security

- Strong password requirements affect the change form
- Login form “Forgot password?” link must point at the core page

---

## Developer notes (when you need to debug code)

PieceLocation / hookMain logic`includes/core/class-password.php`Shortcode`[ultimatemember_password]`Request process`um_reset_password_process_hook`Change process`um_change_password_process_hook`Send mail`UM()->user()->password_reset()` → `resetpw_email`Kill sendingfilter `um_disable_email_notification_sending`Core page URL`um_get_core_page( 'password-reset' )`Key APIWP `get_password_reset_key` / `check_password_reset_key` / `reset_password`Custom code that calls `UM()->password()->reset_url()` multiple times in one request is safe (static key cache). Regenerating keys elsewhere between “email built” and “user clicks” will invalidate the emailed link.

---

## Minimum production harden list

1. Assign a published Password Reset page with `[ultimatemember_password]`.
2. Exclude that page (and auth pages) from all full-page caches/CDNs.
3. Use authenticated SMTP with a From address on your domain.
4. Keep Password Reset Email enabled; understand checkemail ≠ mail sent.
5. Know that approved-only and attempt limits silently or loudly block resets.
6. Tell users: one click, same browser, cookies allowed, request a new link after any error.

---

Most “UM password reset is broken” tickets resolve to: wrong/missing reset page, mail never left the server, cookie blocked or path-mismatched, or cached HTML short-circuiting the cookie redirect. Fix those four before assuming a plugin bug.
