fullstackhero/dotnet-starter-kit · error · CustomException
failed to change password
Error message
failed to change password
What it means
ChangePasswordAsync throws CustomException('failed to change password') when userManager.ChangePasswordAsync returns result.Succeeded == false. Typical Identity failures: wrong current password, new password below policy, or password reuse rules; the Identity error descriptions are attached to the exception.
Solutions
- Read the errors list on the exception — Identity reports the exact reason (e.g. 'PasswordTooShort', 'PasswordMismatch')
- Retry with the correct current password
- Pick a password meeting the configured Identity strength requirements
- Normalize/trim inputs client-side before submission
Example fix
// before
throw new Exception("change failed");
// after
var errors = result.Errors.Select(e => e.Description).ToList();
throw new CustomException("failed to change password", errors); Defensive patterns
Strategy: try-catch
Validate before calling
if (newPassword != confirmNewPassword)
return Results.BadRequest("Passwords do not match.");
if (newPassword is null || newPassword.Length < 8)
return Results.BadRequest("Password must be at least 8 characters."); Try / catch
try
{
await passwordService.ChangePasswordAsync(currentPassword, newPassword, confirmNewPassword, userId, ct);
}
catch (CustomException ex)
{
return Results.BadRequest(new { message = ex.Message, identityErrors = ex.Errors });
} Prevention
- Surface the Identity error descriptions (e.g. PasswordMismatch, PasswordTooShort) in the UI
- Mirror the configured Identity password policy client-side
- Trim/normalize inputs before submission
- Prompt the user to re-enter the current password after a PasswordMismatch failure
When it happens
Trigger: Calling ChangePasswordAsync with an incorrect current password; newPassword violating strength/length/uniqueness policy; confirmNewPassword mismatching newPassword is caught earlier by validation, but Identity-side policy failures surface here.
Common situations: User typo in the current password; new password too weak per configured Identity options; account locked or password recently changed violating reuse policy; client sends untrimmed input with stray whitespace.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- System role permissions are managed by the framework and…
- The authenticator code is invalid.
- UserId must be provided.
- error resetting password
- Update profile failed
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/254c42a1f04851ae.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Identity/Modules.Identity/Services/UserPasswordService.cs:98
// Raise domain event for password reset
var tenantId = multiTenantContextAccessor?.MultiTenantContext?.TenantInfo?.Id;
user.RecordPasswordChanged(wasReset: true, tenantId);
await db.SaveChangesAsync(cancellationToken);
}
public async Task ChangePasswordAsync(string password, string newPassword, string confirmNewPassword, string userId, CancellationToken cancellationToken = default)
{
var user = await userManager.FindByIdAsync(userId);
_ = user ?? throw new NotFoundException("user not found");
var result = await userManager.ChangePasswordAsync(user, password, newPassword);
if (!result.Succeeded)
{
var errors = result.Errors.Select(e => e.Description).ToList();
throw new CustomException("failed to change password", errors);
}
// Raise domain event for password change
var tenantId = multiTenantContextAccessor?.MultiTenantContext?.TenantInfo?.Id;
user.RecordPasswordChanged(wasReset: false, tenantId);
await db.SaveChangesAsync(cancellationToken);
// Update password expiry date
await passwordExpiryService.UpdateLastPasswordChangeDateAsync(userId, cancellationToken);
// Save to history
await passwordHistoryService.SavePasswordHistoryAsync(userId, cancellationToken);
}
private void EnsureValidTenant()
{
if (string.IsNullOrWhiteSpace(multiTenantContextAccessor?.MultiTenantContext?.TenantInfo?.Id))
{View on GitHub (pinned to 3f2959e683)