Short answer
Ask the user to solve an MFA challenge: challenge and verify one of their factors, which moves the session to aal2, then retry the call. Use getAuthenticatorAssuranceLevel() to decide when to show the MFA screen instead of waiting for the error.
Rather not fix it yourself? App Fix Ticket starts with a fixed-price diagnosis, then a fixed price for the fix before any fix work.
Why the session is not aal2, and the fix
01
The user skipped the MFA step after signing in
“To call this API, the user must have a higher Authenticator Assurance Level. To resolve, ask the user to solve an MFA challenge.” Supabase docs, Auth error codes (insufficient_aal)
Signing in with a password or a magic link gives aal1. Show the MFA screen after sign-in for users who have a verified factor, and only continue once verification succeeds.
02
The user is removing a factor before verifying
“users can only unenroll a factor after completing the enrollment flow and obtaining an aal2 JWT claim.” Supabase docs, Multi-Factor Authentication
Supabase’s MFA guide says users can only unenroll after obtaining an aal2 claim. Verify a factor first, then unenroll.
03
The app reads the level too late
“Use the supabase.auth.mfa.getAuthenticatorAssuranceLevel() method to get easy access to this information in your browser app.” Supabase docs, Multi-Factor Authentication
Check the assurance level when the app loads, not after a request fails. getAuthenticatorAssuranceLevel() reads it from the session.
04
An old token is still in use
“This assurance level is encoded in the aal claim in the JWT associated with the user.” Supabase docs, Multi-Factor Authentication
Also check: the level is stored in the JWT, so a request sent with a token from before verification still carries aal1. Send requests with the session from after verification.
Checked against the vendor’s docs on : Supabase docs: Auth error codes; Supabase docs: Multi-Factor Authentication.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
“Very responsive, attentive to fixing bugs, and completed the project as needed! Thank you!”
Related: Supabase mfa_verification_failed · Supabase new row violates row-level security · Supabase over_sms_send_rate_limit · Supabase Edge Function WORKER_LIMIT