"User is already enrolled" error when enrolling more than one MFA factors using MFA API

Problem Statement

I used the Auth0 MFA api and tried to give the user to select email and SMS, but received the “User is already enrolled” error.

Here are the steps:

  1. I created a user who is required to verify with MFA
  2. The user selected SMS for MFA and enrolled phone number, and did all things to get the id token. It worked perfectly.
  3. However, Next time the user wants to verify with another method, which is email, Auth0 returns the “User is already enrolled” error.

Troubleshooting

This document Enroll and Challenge Email Authenticators says:

If you get a ``User is already enrolled error, the user already has an MFA factor enrolled. Before associating another factor with the user, you must challenge the user with the existing factor.

Cause

There are two types of MFA token:

  1. If the MFA is enabled and the user tries to log in via ROPG, an MFA token is returned to call the MFA API for MFA challenges. This MFA token can also be used to enroll MFA if the user has no existing enrolled MFA factors. This MFA token looks like this “Fe26.2*bff…”
  2. Request an access token with audience of [https://YOUR_DOMAIN/mfa/](https://your_domain/mfa/)via ROPG or GET /authorize endpoint. Depending on the scopes granted, this MFA token can be used to enroll, list, and delete MFA factors.
    Manage Authenticator Factors with Auth0 MFA API
    This MFA token is a JWT

The customer is using the MFA token of type 1 to enroll the 2nd MFA factor (email). That’s why it failed with the error.

Solution

Here are the steps to enroll 2nd and the further factors.

  1. Obtain the MFA Token with audience of [https://YOUR_DOMAIN/mfa/](https://your_domain/mfa/) and scope of enroll
    You can obtain the MFA token via Universal Login or Resource Owner Password Grant, as described in this doc.

For example, here is an example curl command that requests for the MFA token via Resource Owner Password Grant:

curl --request POST \
  --url 'https://YOUR_DOMAIN/oauth/token' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=password \
  --data username=user@example.com \
  --data password=pwd \
  --data 'client_id=YOUR_CLIENT_ID' \
  --data client_secret=YOUR_CLIENT_SECRET \
  --data audience=https://YOUR_DOMAIN/mfa/ \
  --data 'scope=enroll'
  1. The MFA token request in step 1 may require an MFA challenge (with the 1st factor SMS). Complete the MFA challenge with SMS as usual, and then the MFA token is issued as “access_token” in the response.
    If you decode the issued access_token (e.g. using https://jwt.io), you should see the "aud": "[https://YOUR_DOMAIN/mfa/](https://your_domain/mfa/)" and "scope": "enroll" in the payload.

  2. Use the MFA token obtained in step #2 to enroll the email factor as described in this doc.