Authenticate (Code: 20003) error with an auth0_idp error

We are encountering an Authenticate (Code: 20003) error with an auth0_idp_error when attempting to create a user via the Auth0 Management API’s /api/v2/users endpoint from our backend application.

This issue is currently affecting our production environment. It was functioning without problems until about a week ago, making this a critical issue for us right now.

We are using a Machine to Machine application (Grizzly Server API Management New) with the Client Credentials flow to obtain a token for the Auth0 Management API audience (https://grizzlyapp.auth0.com/api/v2/).

We have verified that:

  • The backend uses the correct credentials and audience to obtain the M2M token.
  • The M2M token has the necessary permissions for the Management API (e.g., read:roles, create:users) as confirmed by a successful curl test to /api/v2/roles using the token.
  • The backend calls the Management API endpoints (/api/v2/…) on our custom Auth0 domain (auth.grizzlyforce.ca) with correct URL construction.
  • The database connection name (Username-Password-Authentication) used in the user creation request matches the name in Auth0.
  • Custom database scripts are not enabled for this connection.
  • We are within our free plan limits for MAUs and M2M tokens.

{
error: Error: Error: Authenticate (Code: 20003)
at AuthService.createUserAccount (D:\grizzlyserver-rs-stage\packages\server\src\services\AuthService.ts:172:19)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at async AuthService.registerEmployer (D:\grizzlyserver-rs-stage\packages\server\src\services\AuthService.ts:226:27)
at async EmployerResolver.createEmployer (D:\grizzlyserver-rs-stage\packages\server\src\modules\employer\resolver.ts:309:35)
}

private async createUserAccount(
        email: string,
        password: string,
        accountType: AuthAccountTypes,
        connection: string = "Username-Password-Authentication",
        phoneNumber?: string,
    ): Promise<string> {
        try {
            await this.requestAccessToken();

            const params: any = {
                email,
                connection,
                user_metadata: { userType: accountType },
                app_metadata: { roles: [accountType] },
            };

            if (connection === 'Username-Password-Authentication') {
                params.password = password;
            }

            if (connection === 'sms') {
                params.phone_number = phoneNumber;
            }

            const createUserResponse = await fetch(`${this.domain}api/v2/users`, {
                method: "POST",
                headers: this.header,
                body: JSON.stringify(params),
            });

            const createUserJSON: any = await createUserResponse.json();

            if (createUserResponse.status !== 201) {
                throw new Error(createUserJSON.message);
            }

            return createUserJSON.user_id;
        } catch (error) {
            throw new Error(error);
        }

    }
   public async getRoleId(role: AuthAccountRoleNames): Promise<string> {
        await this.requestAccessToken();

        const rolesResponse = await fetch(`${this.domain}api/v2/roles`, {
            method: "GET",
            headers: this.header,
        });

        if (rolesResponse.status !== 200) {
            throw new Error(rolesResponse.statusText);
        }

        const roles: any = await rolesResponse.json();

        const { id } = roles.find(({ name }: { name: string }) => name === role);

        if (!id) {
            throw new Error("Could not find the given role");
        }

        return id;
    }