Quick fix
Assuming your container is named open-webui and the database lives at /app/backend/data/webui.db (the default for Docker volumes). One block to reset the password:
# Replace container name, email and password with your own
docker exec -it open-webui python3 <<'PY'
import bcrypt, sqlite3
EMAIL = "admin@example.com" # admin login email
NEW = "your-new-password-8+chars" # new password
h = bcrypt.hashpw(NEW.encode, bcrypt.gensalt(rounds=12)).decode
con = sqlite3.connect("/app/backend/data/webui.db")
n = con.execute("UPDATE auth SET password=? WHERE email=?", (h, EMAIL)).rowcount
con.commit
print("updated rows:", n) # must be 1; 0 means wrong email
PY
No container restart needed — log in with the new password right away. If updated rows: 0, check the email with SELECT email FROM user.
What you will run into
You set up Open WebUI, set an admin password, and a few days later you can't remember it. There is no "forgot password" link; trying to register a new account is rejected (403); tutorials tell you to edit user.password_hash, but the table has no such column.
The tempting fallback is deleting the container and starting over — which wipes chats, knowledge bases and users. You don't need to: the password is just a bcrypt hash in SQLite, and you can replace it directly.
Why this happens
- Passwords live only in the local database: Open WebUI stores users and passwords in SQLite (bcrypt,
$2b$12$...). There is no email-recovery flow. - Newer versions moved the password column:
mainbuilds (2026-08+) keep passwords in a separateauthtable (id / email / password / active); theusertable no longer haspassword_hash. Most older tutorials targetuser.password_hashand fail withno such column. - Signup is disabled by default: production defaults to
ENABLE_SIGNUP=false, so the "register a fresh account and take over" path returns 403. - The login endpoint changed: current builds use
POST /api/v1/auths/signin(older docs say/login, which returns 405 now).
Password reset is hard because "credentials live only locally and verification is irreversible": Open WebUI stores bcrypt hashes ($2b$12$...) in SQLite and only compares hashes at login — there is no mail service and no "reset" endpoint, so "forgot password" means editing the database.
Three layers of traps: ① table structure evolves with versions — newer builds (from 2026-08) moved passwords from the user table into a separate auth table (id/email/password/active), and old tutorials' user.password_hash fails with no such column on new versions;
② bcrypt hashes cannot be hand-written — a new password must be produced by a bcrypt generator (htpasswd/in-container Python); writing plaintext into the column means login always fails the comparison;
③ signup is disabled by default — with ENABLE_SIGNUP=false the register endpoint returns 403, so "register a new admin to take over" is not an option by default.
Deterministic takeaway: check the version first (image tag via docker ps) to decide which table to edit; generate the new hash with bcrypt before writing; back up webui.db before editing and restart to apply.
Official approach (no python dependency, Docker volume)
The official docs (docs.openwebui.com/troubleshooting/password-reset/) use htpasswd + socat — no python/bcrypt inside the container. It updates the same auth table (id / email / password / active) as the main flow on this page.
Step 1: generate a local bcrypt hash (run on the host; htpasswd comes with apache2-utils, usually present on macOS/Linux):
# replace your-new-password; tr -d ':\n' strips the newline -> one line of hash
htpasswd -bnBC 10 "" "your-new-password" | tr -d ':\n'
Note: any $ in the hash must be triple-escaped (\\\$) before it is used in the Docker command below, or the shell will expand it.
Step 2: write it with one command (replace open-webui with your volume name, HASH with the output above, admin@example.com with the admin email):
docker run --rm -v open-webui:/data alpine/socat EXEC:"bash -c 'apk add sqlite && echo UPDATE auth SET password='\''HASH'\'' WHERE email='\''admin@example.com'\''; | sqlite3 /data/webui.db'", STDIO
Step 2 (fallback, when the one-liner fails): some environments ship alpine/socat without bash; the official alternate method starts an alpine container, installs the tools and updates step by step:
docker run -it --rm -v open-webui:/data alpine
# inside the container, run in order:
apk add apache2-utils sqlite
htpasswd -bnBC 10 "" "your-new-password" | tr -d ':'
sqlite3 /data/webui.db
UPDATE auth SET password='HASH' WHERE email='admin@example.com';
# exit sqlite: Ctrl+D
Local (pip) install: run sqlite3 directly against the data file, no container:
cd <open-webui install dir>
sqlite3 backend/data/webui.db "UPDATE auth SET password='HASH' WHERE email='admin@example.com';"
The docs also state the reset fallback: to completely reset (users, settings, chats, passwords) delete webui.db — the only "full reset" path. Make sure you don't need the data before deleting it.
Step by step
1. Find webui.db for your install — Required (wrong file = wasted effort)
- Docker: data lives in a volume, fixed path
/app/backend/data/webui.dbinside the container. - pip install: data at
~/.open-webui/data/webui.db(connect withsqlite3orpython3while the app is running). - Back up first:
cp webui.db webui.db.bak.
2. Check the schema before editing — Required (schema differs between versions)
docker exec open-webui python3 -c "import sqlite3; con=sqlite3.connect('/app/backend/data/webui.db'); [print(r) for r in con.execute('PRAGMA table_info(auth)')]"
authtable with apasswordcolumn → new layout, updateauth.password(this page).- No
authtable, butuserhaspassword_hash→ old layout (0.5.x and earlier); replaceUPDATE auth SET password=? WHERE email=?withUPDATE user SET password_hash=? WHERE email=?.
3. Look up the admin email — Required (wrong email -> updated rows: 0)
docker exec open-webui python3 -c "import sqlite3; con=sqlite3.connect('/app/backend/data/webui.db'); [print(r) for r in con.execute('SELECT id,email,role FROM user')]"
Note the email of the row with role=admin.
4. Generate a bcrypt hash and write it — Required
docker exec -it open-webui python3 <<'PY'
import bcrypt, sqlite3
EMAIL = "admin@example.com"
NEW = "your-new-password-8+chars"
h = bcrypt.hashpw(NEW.encode, bcrypt.gensalt(rounds=12)).decode
con = sqlite3.connect("/app/backend/data/webui.db")
print("updated:", con.execute("UPDATE auth SET password=? WHERE email=?", (h, EMAIL)).rowcount)
con.commit
PY
5. Log in with the new password — Required
Open your Open WebUI URL and sign in with that email + the new password. Existing sessions on other devices stay valid (doesn't affect recovery).
How to confirm it works
- Sign-in with the new password succeeds and still shows admin (admin panel accessible).
- Sign-in with the wrong password is still rejected — proving the hash was replaced, not the check bypassed.
- API check:
curl -X POST http://localhost:3000/api/v1/auths/signin -H 'Content-Type: application/json' -d '{"email":"...","password":"NEW"}'returns 200 with atoken.
WEBUI_SECRET_KEY: why you can still be logged out after the password change
Changing the password does not require touching WEBUI_SECRET_KEY, and old sessions stay valid (tested on this page). But these cases force everyone offline, unrelated to the password:
- No
WEBUI_SECRET_KEYset: Open WebUI generates a random key on every start; after a restart all old session JWTs are invalid -> everyone must log in again (confirmed by the official FAQ). - The key changed: besides forcing logouts, OAuth tokens / tool API keys are encrypted with this key; after a change they can't be decrypted and you get
Error decrypting tokens(confirmed by the official FAQ). - Multiple instances / shared data volume: all instances must use the same fixed key, otherwise sessions and OAuth state invalidate each other.
So after restoring access, set WEBUI_SECRET_KEY to a fixed long random string (-e WEBUI_SECRET_KEY=... for Docker, environment: in Compose) once and for all.
Other environments
- Open WebUI 0.5.x and earlier: column is
user.password_hash; everything else is the same. - Volume mounted on the host: you can also edit from the host (
sqlite3 <volume-path>/webui.dbplus any bcrypt tool); the safest order is stop container → edit → start. - LDAP / SSO / enterprise login: passwords are managed by the identity provider; editing the local
authtable only affects local accounts. - Forgot the Ollama password instead: Ollama has no auth by default; "cannot connect" is usually
OLLAMA_BASE_URL/ container-localhost — see open-webui-ollama-connect.
Symptom
- Login page says
The email or password provided is incorrectand you can't remember the password. - Signup returns 403
You do not have permission to access this resource. - Following old tutorials, sqlite reports
no such column: password_hash.
Cause
- Passwords are bcrypt hashes in local SQLite with no recovery flow; newer builds moved them to the
authtable (nopassword_hashcolumn); signup is disabled by default (ENABLE_SIGNUP=false), so a fresh account can't take over.
Solution
- Back up
webui.db→ generate a new bcrypt hash with the container's python3 (bcrypt/sqlite3 included) →UPDATE auth SET password=? WHERE email=?(old builds:user.password_hash) → log in immediately; no restart needed.
Verification Evidence
- Test container
owui-pw(ghcr.nju.edu.cn/open-webui/open-webui:main, built 2026-08-25, port 3002): - Wrong password login → HTTP 400
The email or password provided is incorrect; bcrypt.hashpw(..., gensalt(rounds=12))produced a$2b$12$hash (bcrypt 5.0.0 in-container);UPDATE auth SET password=? WHERE email=?→rows updated: 1(written while the app was running; no stop/restart);- Wrong password after the update → still 400; new password → HTTP 200 with
role: admin+ JWT; - New token against
GET /api/v1/auths/→ HTTP 200 (session truly valid); bcrypt.checkpw(new, stored) = True,checkpw(wrong, stored) = False;- Test container and volume cleaned up (
docker rm -f+docker volume rm). local repro log 2026-08-30
References
- Open WebUI docs: Reset Admin Password — <https://docs.openwebui.com/troubleshooting/password-reset/>
- Open WebUI FAQ (WEBUI_SECRET_KEY, logouts, decryption errors) — <https://docs.openwebui.com/faq/>
Related canonicals
Read in order: precondition -> same root / same domain / related:
- Same root:
- Open WebUI RAG retrieval not working / embedding misconfig (same root: webui.db wins over env — auth table for passwords, config table for settings)
- Related (similar errors, different cause):
- Open WebUI shows "cannot connect to Ollama" (adjacent: WebUI account layer vs model channel)
Applicable tools (2)
This problem is linked from the tool pages below — reachable from either side.
dockeropen-webuiSource & evidence
← Local LLM domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk