All dispatchesView as Markdown

Password reset email: 8 secure examples and templates

MC
Maya ChenEmail infrastructure at Email Bump

Write password reset emails for requested, expired, reused, changed, and suspicious states—then implement neutral responses, single-use tokens, and safe session handling.

A password reset email gives someone a short-lived way to prove mailbox access and reach a restricted password-change flow. It should identify the product and account, provide one unambiguous action, state the expiration, explain what happens if the request was not theirs, and avoid revealing secrets or account details that do not belong in email.

The email is one security boundary inside a larger recovery system. Neutral request responses, cryptographically random single-use tokens, trusted URL construction, atomic consumption, request throttling, session invalidation, and a post-change alert matter as much as the words on the button.

Password reset flow and message states

Recovery state machine
REQUESTED -> TOKEN_CREATED -> EMAIL_QUEUED -> LINK_OPENED -> RESET_COMPLETED
      |           |                 |              |
      |           +-> SUPERSEDED   +-> EXPIRED    +-> SESSIONS_REVIEWED
      +-> RATE_LIMITED             +-> ALREADY_USED
      +-> NEUTRAL_NO_ACCOUNT

Every public request receives the same neutral response. Email is sent only when
the account and recovery policy permit it. A token grants reset—not general access.

1. Standard password reset request

Password reset email template
Subject: Reset your [Product] password

Hi [First name or there],

We received a request to reset the password for [masked address / workspace].

[Reset password]

This link expires in [actual lifetime] and can be used once.

If you did not request a reset, your password has not changed. You can ignore
this message or review account security at [non-tokenized safe URL].

Support will never ask you to forward this email or send us the reset link.

Use a subject that names the action and product. The call to action should visibly point to the expected HTTPS domain. Avoid marketing blocks, multiple competing buttons, and language such as ‘urgent’ unless the account is actually under a verified threat.

2. Password reset code

One-time reset code template
Subject: Your [Product] password reset code

Enter this code on the [Product] password reset screen:

[123 456 789]

The code expires in [lifetime] and works once for [masked account]. Do not share
it with anyone, including support. If you did not request it, ignore this email.

Only enter the code on [exact product domain].

A code avoids some link-prefetch problems and can work across devices, but it remains a bearer secret and can be phished. Rate-limit guesses, bind the code to a pending recovery transaction, use sufficient entropy for the allowed attempt count, and never accept it as a general-purpose login credential.

3. Reset requested for an SSO-managed account

SSO recovery template
Subject: Sign-in help for your [Product] account

The account for [masked address] signs in through [verified organization / SSO].
There is no [Product] password to reset for this account.

[Return to sign in]

If your organization’s sign-in is unavailable, contact [approved administrator
or support route]. We did not change the account because of this request.

Do not mint a local password that bypasses enforced SSO. The public request screen should still avoid revealing whether an account exists or which identity provider it uses; this explanation belongs only in email sent to the eligible address under your disclosure policy.

4. Reset link expired

Expired reset state
Page title: This password reset link expired

The link is no longer valid. Password reset links for [Product] expire after
[lifetime]. Request a new one to continue.

[Request a new reset]

For security, we cannot reactivate or extend the old link. If you did not request
this reset, no account change was made.

This is usually a landing-page state, not another automatic email. Let the person request a fresh token through the same neutral, rate-limited process. Do not extend the database expiry merely because an old URL was opened.

5. Reset link already used or superseded

Used reset state
Page title: This password reset link can’t be used

The link was already used, replaced by a newer request, or is otherwise invalid.

If you recently changed your password, sign in with the new password. Otherwise,
request a fresh reset.

[Go to sign in]    [Request a new reset]

Use one generic invalid state when revealing used versus revoked status would help an attacker. Whatever copy appears, the server must reject the token. Atomic consumption ensures two concurrent requests cannot both change the password.

6. Password changed confirmation

Successful password change template
Subject: Your [Product] password was changed

The password for [masked account] changed on [date, time, timezone].

If you made this change, [sign in normally / no action is needed].

If you did not make it, use this fresh account-security route immediately:

[Secure account]

We [invalidated all existing sessions / describe the actual session policy].

Send this only after the password update commits. The security route must not reuse the consumed reset token. OWASP recommends informing the user after a reset, avoiding automatic login, and offering or applying session invalidation according to policy.

7. Too many password reset requests

Inbox-flooding alert template
Subject: Multiple password reset requests for [Product]

We received multiple recent password reset requests for [masked account].
Your password has not changed unless a valid reset was completed.

If these were yours, wait [cooldown] before requesting another link.
If they were not, review account security and confirm your email account is secure.

[Review account security]

Do not send one warning per abusive request and amplify the flood. Aggregate or suppress alerts under a security-owned policy. Rate-limit per account and across network and device signals while maintaining a safe recovery path for legitimate users.

8. Administrator-initiated recovery

Admin-initiated reset template
Subject: An administrator started password recovery for [Product]

[Verified administrator / organization] started a password reset for [masked
account] on [date and timezone]. No password has changed yet.

[Review and reset password]

The link expires in [lifetime] and works once. If this was unexpected, do not
forward the email; contact [security route] and reference [safe event ID].

Administrative recovery needs stronger audit and authorization than ordinary self-service. Identify the action at an appropriate level, record the administrator and reason internally, and never let support agents view or copy the user’s raw reset token.

Implement the reset token safely

  • Generate a cryptographically random token long enough to resist guessing; store only a secure verifier or hash.
  • Bind it to one user, one purpose, one recovery transaction, and a short documented expiry.
  • Build the HTTPS origin from trusted configuration—not an unvalidated Host header or arbitrary redirect parameter.
  • Keep raw tokens out of CDN, proxy, application, analytics, exception, and support logs.
  • Consume with a conditional database update so precisely one valid request wins.
  • Apply the same password policy as normal account setup and store the password with the approved password-hashing system.
  • Do not lock the account merely because a reset was requested; that would let attackers deny service.
  • After completion, follow the documented session invalidation policy and send a separate security notification.

Prevent account enumeration

Neutral request response
If an eligible account exists for that address, we’ll send password reset
instructions. Check your inbox and spam folder. The link expires after [lifetime].

For every submitted address:
- return the same message and status behavior
- keep response timing reasonably uniform
- apply abuse controls
- queue eligible email asynchronously
- do not expose SSO, suspension, or account-existence state on the public form

OWASP specifically recommends consistent messages and response timing for existing and nonexistent accounts, plus controls against automated submissions. Neutrality must cover observable side channels too: response code, body size, redirect behavior, CAPTCHA path, and timing should not make account discovery easy.

Protect the reset page

Remove the token from the address bar as early as the design permits, set a restrictive referrer policy, and load no third-party scripts or images before exchange. The reset page should not allow an arbitrary next URL. Use a restricted recovery session if multiple steps are required, and protect the password-update POST with the controls appropriate to that session.

Delivery is part of account recovery

  • Send through a dedicated authenticated transactional stream isolated from marketing bursts.
  • Queue durably, but never continue submission retries after the token can no longer be used.
  • Tie duplicate jobs to one token and message intent instead of generating several valid recoveries.
  • Track provider acceptance, delay, delivery, bounce, and suppression with a safe message identifier.
  • Let support see timing and delivery state without exposing the link or confirming accounts to unauthorized callers.
  • Test mailbox-provider delays against the advertised token lifetime and safe resend behavior.

Frequently asked questions

What should a password reset email say?

Name the product and account at a safely recognizable level, say that a reset was requested, provide one reset action, state the actual expiration and single-use behavior, and explain that no password changed if the recipient did not request it. Include a separate security or support route.

How long should a password reset link last?

There is no universal duration. Choose the shortest lifetime practical for your users, delivery path, and risk—normally minutes rather than days for consumer web recovery. State it accurately, observe delivery delays, and require a fresh request after expiration.

Should users be logged in after resetting a password?

OWASP advises sending the user through the usual login mechanism rather than automatically logging them in, which avoids adding complexity to authentication and session handling. Whatever policy you choose should be threat-modeled, consistently implemented, and paired with existing-session review or invalidation.