Grafana Error Guide: 'Invalid username or password' — Fix Login Failures
Fix 'Invalid username or password' in Grafana: diagnose forgotten admin passwords, disabled login form, LDAP bind failures, locked accounts, and reset-admin-password recovery.
- #grafana
- #troubleshooting
- #errors
- #authentication
Overview
“Invalid username or password” is Grafana’s generic login rejection for the built-in form and LDAP/basic auth. It is deliberately vague — Grafana does not reveal whether the username or the password was wrong — so the real reason lives in the server log. Causes range from a genuinely wrong password to a disabled login form, a broken LDAP bind, or a wiped admin account after a database reset.
The literal message on the login page:
Invalid username or password
And in the server log, the more specific reason:
level=error msg="Invalid username or password" logger=authn.service
level=error msg="user not found" logger=ldap
The generic UI message plus a specific log line is the pattern: always read the log, not just the screen.
Symptoms
- Login fails with “Invalid username or password” for a known-good user.
- The admin account stops working after a database migration or volume reset.
- LDAP users cannot log in while local users can (or vice versa).
- Repeated failures start returning “User is temporarily locked” (brute-force protection).
Common Root Causes
1. Wrong or forgotten admin password
The admin password was never changed from GF_SECURITY_ADMIN_PASSWORD, or was rotated and forgotten.
2. Admin account reset by a fresh database
A new/empty SQLite or Postgres/MySQL database recreates admin with the bootstrap password, so old credentials no longer work.
3. Login form disabled
[auth] disable_login_form = true (common when OAuth/LDAP is enforced) hides/rejects local login.
4. LDAP bind or search failure
A wrong bind DN/password, search filter, or unreachable LDAP server makes every LDAP login fail as “invalid”.
5. Account locked or disabled
Brute-force lockout, or is_disabled = 1 on the user, rejects otherwise-correct credentials.
Diagnostic Workflow
Step 1: Read the specific reason in the log
sudo journalctl -u grafana-server --no-pager | grep -iE "invalid username|password|ldap|login|locked" | tail -20
kubectl logs deploy/grafana -n monitoring | grep -iE "invalid username|ldap|login" | tail -20
grep -iE "invalid username|ldap|login" /var/log/grafana/grafana.log | tail -20
user not found (LDAP), bind failed, disable_login_form, and temporarily locked each point to a different fix.
Step 2: Reset the admin password from the CLI
grafana-cli admin reset-admin-password 'NewStrongPassw0rd!'
# Container / Kubernetes
kubectl exec -it deploy/grafana -n monitoring -- grafana-cli admin reset-admin-password 'NewStrongPassw0rd!'
sudo systemctl restart grafana-server
This rewrites the admin user’s password directly in the database.
Step 3: Confirm the login form is enabled
# grafana.ini
[auth]
disable_login_form = false # must be false to allow local login
[auth.basic]
enabled = true
If it must stay disabled for SSO, log in via the OAuth/LDAP path instead.
Step 4: Validate LDAP if LDAP users fail
grafana-cli admin --config /etc/grafana/grafana.ini ... # (grafana handles LDAP at runtime)
# Test the bind independently
ldapsearch -x -H ldap://ldap.example.com -D "cn=grafana,dc=example,dc=com" -w "$BIND_PW" \
-b "dc=example,dc=com" "(uid=jdoe)"
# /etc/grafana/ldap.toml
[[servers]]
host = "ldap.example.com"
port = 389
bind_dn = "cn=grafana,dc=example,dc=com"
bind_password = "..."
search_filter = "(uid=%s)"
search_base_dns = ["dc=example,dc=com"]
Step 5: Clear a lockout
Wait out the lockout window or, for a disabled account, re-enable it via the admin API/DB, then confirm the credentials.
Example Root Cause Analysis
After redeploying Grafana in Kubernetes, no one can log in as admin; the old password is rejected. The log:
level=error msg="Invalid username or password" logger=authn.service user=admin
The deployment lost its persistent volume, so Grafana bootstrapped a fresh SQLite database and recreated admin with the value of GF_SECURITY_ADMIN_PASSWORD, which was left at the default. The team’s rotated password lived only in the old (now gone) database.
Fix: grafana-cli admin reset-admin-password in the running pod to set a known password, then mount a persistent volume for /var/lib/grafana (or move to an external Postgres) so the database survives redeploys. Root cause: an ephemeral database resetting the admin account, not a mistyped password.
Prevention Best Practices
- Persist
/var/lib/grafana(or use an external Postgres/MySQL) so redeploys never reset accounts; see more Grafana guides. - Set
GF_SECURITY_ADMIN_PASSWORDfrom a secret and rotate it there, not by hand in the UI only. - Keep
disable_login_formconsistent with your auth strategy and document the SSO login path. - Test LDAP binds with
ldapsearchbefore enabling, and monitorbind failedin the log. - Preserve at least one local admin as a break-glass account even when SSO is primary.
Quick Command Reference
# Specific reason behind the generic message
sudo journalctl -u grafana-server | grep -iE "invalid username|ldap|login|locked" | tail -20
kubectl logs deploy/grafana -n monitoring | grep -iE "invalid username|ldap" | tail -20
# Reset admin password
grafana-cli admin reset-admin-password 'NewStrongPassw0rd!'
kubectl exec -it deploy/grafana -n monitoring -- \
grafana-cli admin reset-admin-password 'NewStrongPassw0rd!'
# Verify login form and LDAP
# grafana.ini -> [auth] disable_login_form = false
ldapsearch -x -H ldap://ldap.example.com -D "cn=grafana,dc=example,dc=com" \
-w "$BIND_PW" -b "dc=example,dc=com" "(uid=jdoe)"
Conclusion
“Invalid username or password” is intentionally generic — the real cause is in the log, and it is usually one of a few things:
- A wrong/forgotten password, fixed with
grafana-cli admin reset-admin-password. - A fresh database that reset the admin account — persist storage so it stops recurring.
- A disabled login form or an enforced SSO path.
- An LDAP bind/search failure, verifiable with
ldapsearch. - A lockout or disabled account.
Read the specific log line first; it turns a vague rejection into a one-command fix.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.