fullstackhero/dotnet-starter-kit · error · CustomException
two_factor_required: An authenticator code is required to…
Error message
two_factor_required: An authenticator code is required to complete sign-in.
What it means
When a user has two-factor authentication enabled, IdentityService.ValidateCredentialsAsync calls VerifyTwoFactorOrThrowAsync; if no authenticator (TOTP) code is supplied alongside the credentials it throws CustomException with 401 and the two_factor_required marker. Login is intentionally incomplete until the second factor is provided.
Solutions
- Include the current 6-digit TOTP code from the authenticator app in the login request (twoFactorCode field).
- Update the client login flow to a two-step login: submit credentials, then prompt for and send the authenticator code.
- If 2FA should not be required, the user/admin can disable two-factor for the account via the identity endpoints.
- Parse the two_factor_required marker in the 401 response to trigger the code-entry UI instead of showing a generic login failure.
Example fix
// before
const res = await login({ email, password }); // 401 two_factor_required
// after
const res = await login({ email, password, twoFactorCode: totpInput }); // succeeds Defensive patterns
Strategy: try-catch
Validate before calling
if (mfaRequired && !totpCode) {
showTwoFactorPrompt();
return; // don't call login without a code
} Try / catch
try { await login({ email, password, twoFactorCode }); }
catch (e) {
if (e.message?.startsWith('two_factor_required')) { setStep('totp'); return; }
throw e;
} Prevention
- Build the login flow with a dedicated 2FA step for accounts with MFA enabled.
- Detect the two_factor_required marker to branch UI instead of failing.
- Keep API scripts in sync when MFA is enforced on service accounts.
- Consider app-specific recovery codes for automation.
When it happens
Trigger: Signing in with correct username/password for a 2FA-enabled account while omitting the twoFactorCode parameter; clients using a legacy login endpoint or DTO that has no code field; MFA enabled server-side after the client login flow was built.
Common situations: User enables authenticator app, old mobile/SPA client stops working; automated scripts doing password-only login; frontend login form lacking the TOTP step; API consumers not aware MFA was enforced.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- two_factor_invalid: The authenticator code is invalid or…
- Unauthorized
- Unauthorized
- Unauthorized
- The authenticator code is invalid.
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/30f508f75f8e53b3.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Identity/Modules.Identity/Services/IdentityService.cs:72
var user = await FindAndValidateUserByCredentialsAsync(email, password);
ValidateUserStatus(user);
ValidateTenantStatus(tenant);
if (user.TwoFactorEnabled)
{
await VerifyTwoFactorOrThrowAsync(user, twoFactorCode);
}
var claims = await BuildUserClaimsAsync(user, tenant.Id, ct);
return (user.Id, claims);
}
private async Task VerifyTwoFactorOrThrowAsync(FshUser user, string? twoFactorCode)
{
if (string.IsNullOrWhiteSpace(twoFactorCode))
{
throw new CustomException(
"two_factor_required: An authenticator code is required to complete sign-in.",
errors: null,
HttpStatusCode.Unauthorized);
}
var valid = await _userManager.VerifyTwoFactorTokenAsync(
user,
_userManager.Options.Tokens.AuthenticatorTokenProvider,
twoFactorCode);
if (!valid)
{
_logger.LogWarning("Invalid two-factor code for user {UserId}", user.Id);
throw new UnauthorizedException("two_factor_invalid: The authenticator code is invalid or expired.");
}
}
public async Task<(string Subject, IEnumerable<Claim> Claims)?>View on GitHub (pinned to 3f2959e683)