odysseus-dev/odysseus · error · HTTPException

Current password is incorrect

Error message

Current password is incorrect

What it means

Raised as HTTP 400 by POST /change-password when auth_manager.change_password(user, current_password, new_password) returns falsy. The auth manager re-verifies the current password before rotating the hash; a mismatch (or an internal failure to update) yields falsy. This is the 'prove you own the account' step for password rotation.

Source

Thrown at routes/auth_routes.py:210

            pass
        return result

    @router.get("/policy")
    async def auth_policy():
        """Return public auth policy constants for the frontend."""
        return auth_manager.policy()

    @router.post("/change-password")
    async def change_password(body: ChangePasswordRequest, request: Request):
        user = _get_current_user(request)
        if not user:
            raise HTTPException(401, "Not authenticated")
        if len(body.new_password) < PASSWORD_MIN_LENGTH:
            raise HTTPException(400, f"Password must be at least {PASSWORD_MIN_LENGTH} characters")
        current_token = request.cookies.get(SESSION_COOKIE)
        ok = await asyncio.to_thread(auth_manager.change_password, user, body.current_password, body.new_password)
        if not ok:
            raise HTTPException(400, "Current password is incorrect")
        await asyncio.to_thread(auth_manager.revoke_user_sessions, user, current_token)
        return {"ok": True}

    # ------------------------------------------------------------------
    # Two-factor authentication
    # ------------------------------------------------------------------

    @router.post("/2fa/setup")
    async def totp_setup(request: Request):
        """Generate a TOTP secret and return the QR code URI."""
        user = _get_current_user(request)
        if not user:
            raise HTTPException(401, "Not authenticated")
        if auth_manager.totp_enabled(user):
            raise HTTPException(400, "2FA is already enabled")
        secret = auth_manager.totp_generate_secret(user)
        if not secret:
            raise HTTPException(500, "Failed to generate secret")

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Re-enter the current (old) password exactly — beware autofill putting the new password in the wrong field.
  2. Clear saved credentials for the site in the password manager, then retry.
  3. If the old password is genuinely forgotten, use the reset flow / admin reset instead of this endpoint.
  4. If ALL users fail after an upgrade, re-hash stored passwords or restore verify compatibility with the old scheme.
Defensive patterns

Strategy: validation

Validate before calling

// Guard against autofill putting the NEW password in the CURRENT field
if (currentPassword === newPassword) warn('Current and new passwords look identical — check autofill');

Try / catch

catch (e) { if (e.status === 400 && /current password/i.test(e.message)) focusField('current_password'); }

Prevention

When it happens

Trigger: Sending a wrong current_password while authenticated; sending an empty current_password; or a user record whose stored hash can't be verified after a hashing-scheme migration (indistinguishable from wrong password at the route level).

Common situations: Password managers auto-filling the NEW password into the CURRENT field, users forgetting which password is active after a recent change, or post-migration legacy hashes that verify_password can't read.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/af7bd14230193c58. Report an issue: GitHub.