{"record":{"id":"c7d44b2cd41207a9","repo":"SonarSource/sonarqube","slug":"user-with-login-s-has-not-been-found","errorCode":null,"errorMessage":"User with login '%s' has not been found","messagePattern":"User with login '(.+?)' has not been found","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/ChangePasswordAction.java","lineNumber":206,"sourceCode":"\n  private void checkPreviousPassword(DbSession dbSession, UserDto user, String password) throws PasswordException {\n    try {\n      localAuthentication.authenticate(dbSession, user, password, AuthenticationEvent.Method.BASIC);\n    } catch (AuthenticationException ex) {\n      throw new PasswordException(OLD_PASSWORD_INCORRECT, \"Incorrect password\");\n    }\n  }\n\n  private static void checkNewPasswordSameAsOld(String newPassword, String previousPassword) throws PasswordException {\n    if (previousPassword.equals(newPassword)) {\n      throw new PasswordException(NEW_PASSWORD_SAME_AS_OLD, \"Password must be different from old password\");\n    }\n  }\n\n  private UserDto getUserOrThrow(DbSession dbSession, String login) {\n    UserDto user = dbClient.userDao().selectByLogin(dbSession, login);\n    if (user == null || !user.isActive()) {\n      throw new NotFoundException(format(\"User with login '%s' has not been found\", login));\n    }\n    return user;\n  }\n\n  private void deleteTokensAndRefreshSession(HttpRequest request, HttpResponse response, DbSession dbSession, UserDto user) {\n    dbClient.sessionTokensDao().deleteByUser(dbSession, user);\n    refreshJwtToken(request, response, user);\n  }\n\n  private void refreshJwtToken(HttpRequest request, HttpResponse response, UserDto user) {\n    jwtHttpHandler.removeToken(request, response);\n    jwtHttpHandler.generateToken(user, request, response);\n  }\n\n  private void updatePassword(DbSession dbSession, UserDto user, String newPassword) {\n    UpdateUser updateUser = new UpdateUser().setPassword(newPassword);\n    userUpdater.updateAndCommit(dbSession, user, updateUser, u -> {\n    });","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/ChangePasswordAction.java#L188-L224","documentation":"SonarQube's user web API (ChangePasswordAction) throws this NotFoundException when the login passed to the change-password endpoint does not resolve to an existing AND active user. The DAO selectByLogin returns null for missing users, and deactived users are treated the same as missing ones so their credentials cannot be manipulated. It is the API's way of saying the target account is absent or disabled.","triggerScenarios":"POST api/users/change_password with a 'login' parameter that matches no user row, or matches a user whose active=false.","commonSituations":"Typo in login; user was deactivated/deleted by an admin; referring to a user by name or email instead of login; user was removed after token/credential cleanup scripts; SAML/LDAP-provisioned account not yet created locally.","solutions":["Verify the login exists and is active: GET api/users/search?q=<login> as an administrator, and confirm the 'login' field (not name or email).","If the user is deactivated, reactivate first via POST api/users/update with active=true (requires Administer System).","Create the user if missing: POST api/users/create with the correct login, then retry the password change.","If login identity comes from an external auth (LDAP/SAML/GitHub), the login may be provisioned on first sign-in — have the user sign in once, then retry.","Check for whitespace/case issues in the login parameter; logins are stored exactly as created."],"exampleFix":"// before: querying by email instead of login\ncurl -u admin:token -X POST 'https://sonar/api/users/change_password?login=jane@corp.com&password=...'\n// after: use the actual login, after verifying it exists\ncurl -u admin:token 'https://sonar/api/users/search?q=jdoe'   # find exact login\ncurl -u admin:token -X POST 'https://sonar/api/users/change_password?login=jdoe&password=...'","handlingStrategy":"validation","validationCode":"const exists = await fetch(`${base}/api/users/search?q=${encodeURIComponent(login)}`, {headers: auth});\nconst {users} = await exists.json();\nconst user = users.find(u => u.login === login && u.active);\nif (!user) throw new Error(`login ${login} missing or inactive; aborting change_password`);","typeGuard":"function isActiveUser(u) {\n  return u != null && typeof u.login === 'string' && u.active === true;\n}","tryCatchPattern":"try {\n  await changePassword(login, newPassword);\n} catch (e) {\n  if (e.status === 404 && /has not been found/.test(e.message)) {\n    // user missing or deactivated: look it up / reactivate before retry\n  } else throw e;\n}","preventionTips":["Resolve logins via api/users/search instead of hardcoding them","Treat deactivated users as not-found in pre-checks","Use the login field, never name or email","Account for SSO first-sign-in provisioning delays"],"tags":["sonarqube","rest-api","user-management","not-found"],"backgroundTag":"user-not-found","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}