SonarSource/sonarqube · error · PasswordException

old_password_incorrect

old_password_incorrect

Error message

Incorrect password

What it means

checkPreviousPassword authenticates the user with the supplied previous password via localAuthentication.authenticate; any AuthenticationException is converted into a PasswordException with code old_password_incorrect and message 'Incorrect password'. This prevents changing a password without knowing the current one.

Solutions

  1. Re-enter the correct current password
  2. Reset the password via admin (api/users/change_password as admin bypasses, or password reset flow) if the old one is lost
  3. Verify the user is a local account, not delegating authentication to an external identity provider

Example fix

// before
POST ...?previous_password=TypoPass&new_password=X
// after
POST ...?previous_password=CorrectCurrentPass&new_password=X
Defensive patterns

Strategy: try-catch

Validate before calling

// no safe pre-check without authenticating; at minimum confirm the account is local
const user = await getUser(login);
if (user.externalIdentity) throw new Error('Non-local users cannot verify previous password locally');

Try / catch

try { await changePassword(login, oldPw, newPw); } catch (e) { if (e.code === 'old_password_incorrect') { rePromptForCurrentPassword(); return; } throw e; }

Prevention

When it happens

Trigger: POST api/users/change_password where previous_password does not match the user's current local password (including after the password was already changed elsewhere).

Common situations: Stale cached password in a form; password changed by SSO/admin meanwhile; users with external (non-local) authentication whose local verification always fails; pasting the new password into the old-password field.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/65f2423d30612b4e. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/ChangePasswordAction.java:193

      checkArgument(SPECIAL_CHARACTER_PATTERN.matcher(newPassword).find(), "Password must contain at least one special character");
    } catch (IllegalArgumentException e) {
      throw new PasswordException(e.getMessage());
    }
  }

  private static String getParamOrThrow(HttpRequest request, String key) throws PasswordException {
    String value = request.getParameter(key);
    if (isNullOrEmpty(value)) {
      throw new PasswordException(format(MSG_PARAMETER_MISSING, key));
    }
    return value;
  }

  private void checkPreviousPassword(DbSession dbSession, UserDto user, String password) throws PasswordException {
    try {
      localAuthentication.authenticate(dbSession, user, password, AuthenticationEvent.Method.BASIC);
    } catch (AuthenticationException ex) {
      throw new PasswordException(OLD_PASSWORD_INCORRECT, "Incorrect password");
    }
  }

  private static void checkNewPasswordSameAsOld(String newPassword, String previousPassword) throws PasswordException {
    if (previousPassword.equals(newPassword)) {
      throw new PasswordException(NEW_PASSWORD_SAME_AS_OLD, "Password must be different from old password");
    }
  }

  private UserDto getUserOrThrow(DbSession dbSession, String login) {
    UserDto user = dbClient.userDao().selectByLogin(dbSession, login);
    if (user == null || !user.isActive()) {
      throw new NotFoundException(format("User with login '%s' has not been found", login));
    }
    return user;
  }

  private void deleteTokensAndRefreshSession(HttpRequest request, HttpResponse response, DbSession dbSession, UserDto user) {

View on GitHub (pinned to 184c821202)