Local LLM · recorded 2026-08-30 · applies to 2 tool(s) ✓ Verified

Problem: Forgot the Open WebUI admin password / can't log in —— Trove problem library

Verified 2026-08-30forgot the Open WebUI admin password — docker exec into the container and run a one-liner password reset (bcrypt + sqlite3 on webui.db).

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

  1. Passwords live only in the local database: Open WebUI stores users and passwords in SQLite (bcrypt, $2b$12$...). There is no email-recovery flow.
  2. Newer versions moved the password column: main builds (2026-08+) keep passwords in a separate auth table (id / email / password / active); the user table no longer has password_hash. Most older tutorials target user.password_hash and fail with no such column.
  3. Signup is disabled by default: production defaults to ENABLE_SIGNUP=false, so the "register a fresh account and take over" path returns 403.
  4. 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.db inside the container.
  • pip install: data at ~/.open-webui/data/webui.db (connect with sqlite3 or python3 while 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)')]"
  • auth table with a password column → new layout, update auth.password (this page).
  • No auth table, but user has password_hash → old layout (0.5.x and earlier); replace UPDATE auth SET password=? WHERE email=? with UPDATE 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 a token.

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_KEY set: 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.db plus 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 auth table 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 incorrect and 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 auth table (no password_hash column); 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:

Applicable tools (2)

This problem is linked from the tool pages below — reachable from either side.

dockeropen-webui

Source & evidence

Recorded Verified ✓ VerifiedApplies to 2 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

← Local LLM domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk