bitwarden/server · error · BadRequestException

User verification failed.

Error message

User verification failed.

What it means

Thrown (HTTP 400, model-state error under an empty key) by POST /devices/update-trust when _userService.VerifySecretAsync(user, model.Secret) returns false. A deliberate 2-second Task.Delay is awaited first to throttle brute-force attempts on the master password / OTP before updating device trust.

Source

Thrown at src/Api/Controllers/DevicesController.cs:178

        }

        return new ProtectedDeviceResponseModel(device);
    }

    [HttpPost("update-trust")]
    public async Task PostUpdateTrust([FromBody] UpdateDevicesTrustRequestModel model)
    {
        var user = await _userService.GetUserByPrincipalAsync(User);

        if (user == null)
        {
            throw new UnauthorizedAccessException();
        }

        if (!await _userService.VerifySecretAsync(user, model.Secret))
        {
            await Task.Delay(2000);
            throw new BadRequestException(string.Empty, "User verification failed.");
        }

        await _deviceService.UpdateDevicesTrustAsync(
            _currentContext.DeviceIdentifier,
            user.Id,
            model.CurrentDevice,
            model.OtherDevices ?? Enumerable.Empty<OtherDeviceKeysUpdateRequestModel>());
    }

    [HttpPost("untrust")]
    public async Task PostUntrust([FromBody] UntrustDevicesRequestModel model)
    {
        var user = await _userService.GetUserByPrincipalAsync(User);

        if (user == null)
        {
            throw new UnauthorizedAccessException();
        }

View on GitHub (pinned to e93b962371)

Solutions

  1. Re-enter the correct master password or current OTP code.
  2. If the password was recently changed, ensure the client has refreshed credentials before retrying.
  3. Use account recovery if the master password is forgotten.
Defensive patterns

Strategy: try-catch

Try / catch

// Secret verification cannot be safely pre-checked client-side; wrap the call and re-prompt on failure.
try {
  await post('/devices/update-trust', { secret, ... });
} catch (e) {
  if (e.isBadRequest && e.modelState?.['']?.includes('User verification failed.')) {
    showSecretPrompt('Incorrect master password or OTP. Try again.');
  } else { throw e; }
}

Prevention

When it happens

Trigger: Incorrect master password supplied; incorrect OTP code; the client is hashing against stale KDF parameters after a parameter change; secret typed for a different account.

Common situations: Caps-lock or wrong keyboard layout; stale client session using an old password after a password change; wrong account; clock drift invalidating TOTP.

Related errors


AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13). Data as JSON: /api/errors/22d12d21778a7ef4. Report an issue: GitHub.