HeyPuter/puter · error · HttpError
password_mismatch
password_mismatch
Error message
Incorrect password.
What it means
Returned by POST /login when bcrypt.compare(password, user.password) returns false — the password is syntactically valid and the account has a password hash, but the supplied password does not match it. The legacy code 'password_mismatch' distinguishes a wrong password from the no-password (unauthorized) and suspended (account_suspended) cases. All three return HTTP 401.
Source
Thrown at src/backend/controllers/auth/AuthController.ts:433
}
if (user.suspended) {
throw new HttpError(401, 'This account is suspended.', {
legacyCode: 'account_suspended',
});
}
if (user.password === null) {
throw new HttpError(401, 'Incorrect password.', {
legacyCode: 'unauthorized',
});
}
// Verify password
const passwordMatch = await bcrypt.compare(
password,
user.password as string,
);
if (!passwordMatch) {
throw new HttpError(401, 'Incorrect password.', {
legacyCode: 'password_mismatch',
});
}
const reauthAuthId = this.#extractAuthIdFromReauthToken(
req.body.reauth_token,
);
await this.#enforceAuthIdMatch(req, user, reauthAuthId);
// OTP branching — if 2FA enabled, return a short-lived OTP JWT.
// Re-bind the verified `auth_id` into the JWT so the follow-up
// OTP/recovery call can re-enforce the match without re-trusting
// a free-form claim from the client.
if (user.otp_enabled) {
const otpClaims: Record<string, unknown> = {
user_uid: user.uuid,
purpose: 'otp-login',
};View on GitHub (pinned to 908ec23eda)
Solutions
- Use the password-reset flow to set a new password.
- Verify caps-lock and keyboard layout; retype the password.
- Send the raw password string (not a client-side hash) — the server hashes via bcrypt.
Example fix
// before: client pre-hashes the password
await fetch('/login', { method:'POST', body:JSON.stringify({ username, password: sha256(pwd) }) });
// after: send the raw password, let the server bcrypt-compare
await fetch('/login', { method:'POST', body:JSON.stringify({ username, password: pwd }) }); Defensive patterns
Strategy: try-catch
Try / catch
try { await login(username, password); }
catch (e) {
if (e.code === 'password_mismatch') { /* show 'wrong password' + reset link */ }
else throw e;
} Prevention
- Send the raw password, not a client-side hash.
- Provide a password-reset link alongside the wrong-password error.
When it happens
Trigger: User typed the wrong password; caps-lock or layout issue; password was changed recently; client sent an old/hashed password instead of the raw password.
Common situations: Forgotten password; stale cached credentials; password recently rotated; user confused between two accounts.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/77db0526bffdc50e.
Report an issue: GitHub.