Password Reset
Self-service password recovery with secure email links. Users can reset forgotten passwords without admin intervention.
Password Reset Flow
How users recover their password.
Users can reset forgotten passwords through a secure, self-service flow. The process uses time-limited email links to verify identity.
Request Password Reset
Page location: apps/web/app/[locale]/auth/password-reset/page.tsx Route: /auth/password-reset

Users access this page via the "Forgot your password?" link on the sign in page. They enter their email address to receive a reset link.
Component
packages/auth/src/components/password-reset-request-container.tsx
<PasswordResetRequestContainer redirectPath="/reset-password"/>Security Considerations
- The form always shows a success message, even if the email doesn't exist (prevents email enumeration)
- Reset tokens are single-use and time-limited
- Previous reset tokens are invalidated when a new one is requested
Reset Email
When a password reset is requested, Better Auth:
- Generates a secure, random token
- Stores the token with an expiration time
- Sends an email with the reset link
Email Template
Customize the reset email at:
packages/better-auth/src/emails/send-reset-password-email.ts
export async function sendResetPasswordEmail({ email, url, token, productName, language,}: SendResetPasswordEmailOptions) { // Email sending logic}Development Mode
In development, the reset link is logged to the console:
[info] Sending password reset email... email: user@example.com url: http://localhost:3000/reset-password?token=...Set New Password
Route: /reset-password

When the user clicks the link in their email, they're taken to a form to enter their new password.
Token Validation
The token in the URL is validated:
- Token exists and hasn't been used
- Token hasn't expired
- User associated with token exists
If validation fails, the user sees an error message and can request a new reset link.
Password Requirements
The new password must meet the same requirements as registration:
| Requirement | Value |
|---|---|
| Minimum length | 8 characters |
| Maximum length | 128 characters |
After Reset
After successfully setting a new password:
- The reset token is invalidated
- All existing sessions for the user are optionally revoked
- User is redirected to the sign in page
- User signs in with their new password
Programmatic Password Reset
For custom flows, use the auth client:
Request Reset
'use client';import { authClient } from '@kit/better-auth/client';async function requestPasswordReset(email: string) { const result = await authClient.requestPasswordReset({ email, redirectTo: '/reset-password', }); if (result.error) { console.error(result.error.message); return; } // Show success message}Complete Reset
'use client';import { authClient } from '@kit/better-auth/client';async function resetPassword(token: string, newPassword: string) { const result = await authClient.resetPassword({ token, newPassword, }); if (result.error) { console.error(result.error.message); return; } // Redirect to sign in window.location.href = '/auth/sign-in';}Configuration
Password reset is enabled automatically when email/password authentication is enabled:
packages/better-auth/src/auth.ts
emailAndPassword: { enabled: process.env.NEXT_PUBLIC_AUTH_PASSWORD === 'true', requireEmailVerification: true, sendResetPassword: sendResetPasswordEmail, // Email handler},Token Expiration
By default, reset tokens expire after 1 hour. This is configured in Better Auth's settings.
Common Issues
"Invalid or expired token" Error
- Token has already been used (single-use)
- Token has expired (request a new one)
- URL was truncated or modified
Reset Email Not Received
- Check spam/junk folder
- Verify mailer configuration
- Ensure the email exists in the database
- In development, check the console for logged URLs
User Still Can't Sign In After Reset
- Make sure they're using the new password
- Check if email verification is still pending
- Verify the account isn't locked or banned
Previous: Sign Up ← | Next: Session Handling →