{"record":{"id":"22d12d21778a7ef4","repo":"bitwarden/server","slug":"user-verification-failed-22d12d","errorCode":null,"errorMessage":"User verification failed.","messagePattern":"User verification failed\\.","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Controllers/DevicesController.cs","lineNumber":178,"sourceCode":"        }\n\n        return new ProtectedDeviceResponseModel(device);\n    }\n\n    [HttpPost(\"update-trust\")]\n    public async Task PostUpdateTrust([FromBody] UpdateDevicesTrustRequestModel model)\n    {\n        var user = await _userService.GetUserByPrincipalAsync(User);\n\n        if (user == null)\n        {\n            throw new UnauthorizedAccessException();\n        }\n\n        if (!await _userService.VerifySecretAsync(user, model.Secret))\n        {\n            await Task.Delay(2000);\n            throw new BadRequestException(string.Empty, \"User verification failed.\");\n        }\n\n        await _deviceService.UpdateDevicesTrustAsync(\n            _currentContext.DeviceIdentifier,\n            user.Id,\n            model.CurrentDevice,\n            model.OtherDevices ?? Enumerable.Empty<OtherDeviceKeysUpdateRequestModel>());\n    }\n\n    [HttpPost(\"untrust\")]\n    public async Task PostUntrust([FromBody] UntrustDevicesRequestModel model)\n    {\n        var user = await _userService.GetUserByPrincipalAsync(User);\n\n        if (user == null)\n        {\n            throw new UnauthorizedAccessException();\n        }","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Controllers/DevicesController.cs#L160-L196","documentation":"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.","triggerScenarios":"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.","commonSituations":"Caps-lock or wrong keyboard layout; stale client session using an old password after a password change; wrong account; clock drift invalidating TOTP.","solutions":["Re-enter the correct master password or current OTP code.","If the password was recently changed, ensure the client has refreshed credentials before retrying.","Use account recovery if the master password is forgotten."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Secret verification cannot be safely pre-checked client-side; wrap the call and re-prompt on failure.\ntry {\n  await post('/devices/update-trust', { secret, ... });\n} catch (e) {\n  if (e.isBadRequest && e.modelState?.['']?.includes('User verification failed.')) {\n    showSecretPrompt('Incorrect master password or OTP. Try again.');\n  } else { throw e; }\n}","preventionTips":["Re-type the master password rather than retrying a stale cached value.","Sync the client to the current password before secret-verified device operations.","Avoid repeated blind retries due to the built-in throttle."],"tags":["authentication","verification","master-password","throttle","devices","brute-force"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}