auth
auth copied to clipboard
resetPasswordForEmail + MFA: Cannot update password due to AAL2 requirement
Bug report
- [ ] I confirm this is a bug with Supabase, not with my own application.
- [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.
Describe the bug
When I initiate a password reset using supabase.auth.resetPasswordForEmail(email), the user receives the reset link and is redirected correctly. However, when trying to update the password using supabase.auth.updateUser({ password }), Supabase responds with a 401 Unauthorized error, stating that AAL2 is required.
Context
- The user has MFA enabled (TOTP or SMS).
- The session obtained from the recovery link works (getSession() returns a valid session).
- However, the session is AAL1, and Supabase rejects the password update due to AAL2 not being satisfied.
- Calling setSession() does not resolve the issue.
Expected behavior
When using resetPasswordForEmail(), I would expect that the session obtained from the recovery link allows the user to reset their password — even if MFA is enabled — since the reset link was securely sent via email.
If this is not intended, it would be great to have:
- A workaround or documented flow to support password reset when MFA is enabled.
- Clarification in the docs that resetPasswordForEmail() cannot be used if MFA is active unless the user also completes MFA.
Steps to Reproduce
- Enable MFA for a user.
- Trigger resetPasswordForEmail().
- Click on the recovery link and set the session.
- Try calling updateUser({ password }).
- Receive a 401 with AAL2 required.
Could you please clarify:
- Is this the expected behavior?
- If so, how should developers allow users to reset passwords when MFA is enabled?
More info:
Error and logs from Supabase Auth Logs dashboard:
{
"event_message": "{\"component\":\"api\",\"error\":\"401: AAL2 session is required to update email or password when MFA is enabled.\",\"level\":\"info\",\"method\":\"PUT\",\"msg\":\"401: AAL2 session is required to update email or password when MFA is enabled.\",\"path\":\"/user\",\"referer\":\"http://localhost:4200/\",\"remote_addr\":\"XXX\",\"request_id\":\"945dfb2d4397ed16-MXP\",\"time\":\"2025-05-26T14:32:18Z\"}",
"id": "077d00dc-95d2-461c-a014-b94f75e457c9",
"metadata": [
{
"host": "db-qdevaaylziztqvcidnmk",
"component": "api",
"_SYSTEMD_CGROUP": null,
"grant_type": null,
"request_id": "945dfb2d4397ed16-MXP",
"mail_from": null,
"message": null,
"_SOURCE_REALTIME_TIMESTAMP": null,
"PRIORITY": null,
"_AUDIT_LOGINUID": null,
"panic": null,
"metering": null,
"UNIT": null,
"event": null,
"SYSLOG_FACILITY": null,
"msg": "401: AAL2 session is required to update email or password when MFA is enabled.",
"mail_type": null,
"EXECUTABLE": null,
"user_id": null,
"_CMDLINE": null,
"action": null,
"auth_event": [],
"level": "info",
"_PID": null,
"path": "/user",
"duration": null,
"_COMM": null,
"sso_provider_id": null,
"header": null,
"_MACHINE_ID": null,
"login_method": null,
"_STREAM_ID": null,
"source_type": null,
"_LINE_BREAK": null,
"_EXE": null,
"_AUDIT_SESSION": null,
"_TRANSPORT": null,
"x_forwarded_proto": null,
"time": null,
"mail_to": null,
"_GID": null,
"stack": null,
"x_forwarded_host": null,
"saml_entity_id": null,
"status": null,
"_UID": null,
"valid_until": null,
"method": "PUT",
"CODE_FILE": null,
"remote_addr": "XXX",
"provider": null,
"_SYSTEMD_UNIT": null,
"issuer": null,
"error": "401: AAL2 session is required to update email or password when MFA is enabled.",
"client_id": null,
"MESSAGE_ID": null,
"url": null,
"referer": "http://localhost:4200/",
"_SYSTEMD_INVOCATION_ID": null,
"CODE_FUNC": null,
"_BOOT_ID": null,
"INVOCATION_ID": null,
"__MONOTONIC_TIMESTAMP": null,
"timestamp": null,
"__REALTIME_TIMESTAMP": null,
"CODE_LINE": null,
"_SYSTEMD_SLICE": null,
"count": null,
"instance_id": null,
"args": [],
"SYSLOG_IDENTIFIER": null,
"metadata": [],
"_CAP_EFFECTIVE": null,
"factor_id": null,
"_SELINUX_CONTEXT": null,
"expires_in": null,
"version": null,
"project": null
}
],
"timestamp": 1748269938000000
}