Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Grafana By James Joyner IV · · 9 min read

Grafana Error Guide: 'LDAP: Bind failed' — Fix Grafana LDAP Authentication

Quick answer

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
Free toolkit

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) or Result Code 32 (no such object, bad base DN).
  • TLS variants show connection reset or x509 before any bind attempt.

Common Root Causes

  • Wrong bind_dn or bind_password for the service account Grafana uses to search the directory.
  • Incorrect search_base_dns / search_filter so the user object is never found (Result Code 32 or empty result).
  • Wrong bind_dn template 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_password via an env var / secret, not inline, and exclude the service account from interactive password-expiry policies.
  • Test config changes with grafana-cli admin ldap-debug before restarting in production.
  • Match search_filter to the directory (sAMAccountName for AD, uid for OpenLDAP) and scope search_base_dns to the right OUs.
  • Use ldaps:// or start_tls with a trusted CA; avoid ssl_skip_verify = true outside debugging.
  • Alert on the Grafana log pattern Failed to perform LDAP bind so a rotated bind password is caught before users notice.
  • Document the bind-account lifecycle with the directory team so rotations update ldap.toml in 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.

Free download · 368-page PDF

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.