auth icon indicating copy to clipboard operation
auth copied to clipboard

resetPasswordForEmail + MFA: Cannot update password due to AAL2 requirement

Open pierfreeman opened this issue 7 months ago • 11 comments

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:

Image

{
  "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
}

pierfreeman avatar May 26 '25 15:05 pierfreeman