Grafana Error Guide: 'LDAP: Bind failed' — Fix Grafana LDAP Authentication
Fix Grafana 'LDAP: Bind failed' logins: correct the bind DN and password, search filter, and user DN template, fix TLS, and debug with grafana-cli ldap tools.
- #grafana
- #observability
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
Grafana logs this when it tries to authenticate a user against an LDAP or Active Directory server and the bind operation is rejected. The user sees a generic “Invalid username or password” in the UI, but the server log carries the real cause:
lvl=eror msg="Failed to perform LDAP bind" error="LDAP Result Code 49 \"Invalid Credentials\""
Related bind failures appear as:
lvl=eror msg="Error while trying to authenticate user" error="LDAP: Bind failed"
Result Code 49 is the LDAP “invalid credentials” code — it can mean the service account bind DN/password is wrong, or the user’s credentials failed, and telling those two apart is the whole diagnosis.
Symptoms
- All users fail to log in via LDAP, while local admin still works → the service-account (bind DN) credentials are wrong.
- Only some users fail → search filter or user-DN template doesn’t match those users.
- Login worked until a password rotation or directory change → bind account password expired/rotated.
- Grafana log shows
Result Code 49(invalid credentials) orResult Code 32(no such object, bad base DN). - TLS variants show
connection resetorx509before any bind attempt.
Common Root Causes
- Wrong
bind_dnorbind_passwordfor the service account Grafana uses to search the directory. - Incorrect
search_base_dns/search_filterso the user object is never found (Result Code 32 or empty result). - Wrong
bind_dntemplate in single-bind mode (cn=%s,ou=users,...) that doesn’t match the directory’s DN structure. - Expired or rotated service-account password not updated in
ldap.toml. - Directory requires TLS but Grafana connects plaintext (or vice versa), or the CA isn’t trusted.
- Account restrictions — the bind account is locked, disabled, or the user is outside the allowed OU.
Diagnostic Workflow
1. Read the real error in the Grafana log. The UI hides it; the log names the LDAP result code:
journalctl -u grafana-server --since '10 min ago' | grep -i 'ldap\|bind'
Result Code 49 = credentials; Result Code 32 = bad base DN / user not found; TLS errors precede the bind.
2. Use Grafana’s built-in LDAP debugger. It tests the config without a browser and prints exactly which step fails:
# Verify the config parses and the server is reachable
grafana-cli admin ldap-debug --config /etc/grafana/grafana.ini <username>
# In newer builds, enable the debug page: /admin/ldap (requires ldap debug enabled)
3. Test the service-account bind directly with ldapsearch. This isolates the bind DN/password from Grafana:
ldapsearch -x -H ldaps://dc.example.com:636 \
-D "cn=grafana-svc,ou=svc,dc=example,dc=com" -w "$BIND_PASSWORD" \
-b "ou=users,dc=example,dc=com" "(sAMAccountName=jdoe)" dn
If this fails with code 49, the bind account is the problem. If it succeeds but returns no entry, the search base/filter is wrong.
4. Verify the LDAP config. Common fields in /etc/grafana/ldap.toml:
[[servers]]
host = "dc.example.com"
port = 636
use_ssl = true
start_tls = false
ssl_skip_verify = false
root_ca_cert = "/etc/grafana/ca.crt"
bind_dn = "cn=grafana-svc,ou=svc,dc=example,dc=com"
bind_password = "${LDAP_BIND_PASSWORD}"
search_filter = "(sAMAccountName=%s)"
search_base_dns = ["ou=users,dc=example,dc=com"]
Ensure [auth.ldap] enabled = true and config_file points at this file in grafana.ini.
5. Reload and re-test. After editing, restart Grafana and watch the log during a login:
sudo systemctl restart grafana-server
journalctl -u grafana-server -f | grep -i ldap
Example Root Cause Analysis
After an Active Directory maintenance window, every Grafana user suddenly failed to log in, while the local admin account still worked. The UI said “Invalid username or password” for everyone — suspiciously uniform.
The Grafana log showed Failed to perform LDAP bind ... Result Code 49 "Invalid Credentials" on the service account bind, before any user was even searched. ldapsearch with the configured bind_dn and password reproduced code 49 immediately. The AD team had enforced a password policy that expired the grafana-svc account’s password during the window.
Fix: reset the service-account password, updated bind_password (via the ${LDAP_BIND_PASSWORD} env reference), and marked the account “password never expires” per the org’s service-account policy. Logins recovered instantly. The uniform failure across all users was the tell that the bind account — not any individual user — was at fault.
Prevention Best Practices
- Store
bind_passwordvia an env var / secret, not inline, and exclude the service account from interactive password-expiry policies. - Test config changes with
grafana-cli admin ldap-debugbefore restarting in production. - Match
search_filterto the directory (sAMAccountNamefor AD,uidfor OpenLDAP) and scopesearch_base_dnsto the right OUs. - Use
ldaps://orstart_tlswith a trusted CA; avoidssl_skip_verify = trueoutside debugging. - Alert on the Grafana log pattern
Failed to perform LDAP bindso a rotated bind password is caught before users notice. - Document the bind-account lifecycle with the directory team so rotations update
ldap.tomlin lockstep.
Quick Command Reference
# See the real LDAP error
journalctl -u grafana-server --since '10 min ago' | grep -i 'ldap\|bind'
# Grafana's LDAP debugger for one user
grafana-cli admin ldap-debug --config /etc/grafana/grafana.ini jdoe
# Test the service-account bind directly
ldapsearch -x -H ldaps://dc.example.com:636 -D "$BIND_DN" -w "$BIND_PASSWORD" \
-b "$SEARCH_BASE" "(sAMAccountName=jdoe)" dn
# Restart and watch a live login
sudo systemctl restart grafana-server && journalctl -u grafana-server -f | grep -i ldap
Conclusion
LDAP: Bind failed (Result Code 49) almost always comes down to which bind failed: the service account or the user. Read the Grafana server log for the real code, reproduce the service-account bind with ldapsearch, and check the search base/filter separately from credentials. A uniform failure across all users points at the bind account — often an expired service-account password — while per-user failures point at the search filter or user-DN template.
More Grafana prompts & error guides
Every Grafana AI prompt and troubleshooting guide, in one place.
Get 500 Battle-Tested DevOps AI Prompts — Free
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.