Fix LDAP Invalid Credentials Error 49 in 389 Directory Server

Fix LDAP error 49 in 389 Directory Server by checking the password, bind DN, account state, access logs, application secrets, and replication credentials.

Published

Updated

Read time 11 min read

Reviewed byDeepak Prasad

Fix LDAP invalid credentials error 49 in 389 Directory Server by cause — wrong password, bind DN, account state, application secrets, and replication credentials
Tested on Rocky Linux 10.2 (Red Quartz)
Package 389-ds-base 3.2.0-8.el10_2
Applies to RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora
Privilege sudo or root
Scope Fix LDAP bind failures with error 49: password, bind DN, account state, logs, and application secrets. Does not cover unrelated LDAP error codes.
Related guides Install 389 Directory Server
Reset Directory Manager password
dsconf commands
Password storage schemes
Fix LDAP works but LDAPS fails

LDAP result code 49 means 389 Directory Server rejected the credentials presented during a bind. Clients usually print:

text
ldap_bind: Invalid credentials (49)

That message appears in ldapwhoami, ldapsearch, application logs, SSSD, Apache mod_authnz_ldap, and replication status output. Error 49 is an authentication failure. Authorization and ACIs apply only after a successful bind, so changing ACIs will not fix a bind that never authenticates.

RFC 4511 defines result code 49 as invalidCredentials, 19 as constraintViolation, and 53 as unwillingToPerform. Always read the diagnostic message alongside the number. In 389 DS, 49 usually identifies invalid credentials, 19 commonly identifies active password-policy lockout or inactivity constraints, and 53 can identify an operation blocked until the user changes a temporary password or a manually inactivated account is restored.

Use the cause table below to jump to the fix that matches your situation. Password-policy design, lockout thresholds, replication agreement management, and client integration stay in the linked chapters.

IMPORTANT
This article covers LDAP result code 49 and closely related bind failures in 389 Directory Server. It does not cover Microsoft Active Directory subcodes such as 52e, 533, 701, 773, or 775, authorization failures after a successful bind (error 50), or TLS handshake problems that fail before any bind is attempted.

Examples use instance ldap1 on ldap1.example.com:389 with suffix dc=example,dc=com and user uid=user1,ou=people,dc=example,dc=com. Create a disposable test user through manage users and groups before lockout or password-reset exercises, or substitute any existing lab account whose current password you know. Replication examples use agreement ldap1-to-consumer1 and destination consumer1.example.com:1389 from the shared replication lab.


Causes and fixes at a glance

Symptom or situation Likely cause Fix
One user fails; password was recently changed Wrong password Fix wrong password
User exists in search but bind fails Incorrect bind DN Fix incorrect bind DN
New user never authenticated Missing userPassword Fix missing userPassword
Policy warning or grace logins exhausted Expired password Fix expired password
Bind succeeds; later operation returns 53 Mandatory password change Fix expired password
Account was disabled or locked Manual inactivation or policy lockout Fix locked or inactive account
Error changes to 19 after retries Password-policy lockout Fix locked or inactive account
Every user fails; only one replica affected Wrong server or replica Fix wrong LDAP server or replica
Manual bind works; application still fails Stale application secret Fix application credentials
cn=Directory Manager bind fails Wrong Directory Manager password Fix Directory Manager authentication
Replication status reports error 49 Agreement credential mismatch Fix replication authentication
LDAPS fails before any bind result TLS problem, not error 49 TLS chapter

The access log at /var/log/dirsrv/slapd-INSTANCE/access records bind requests and bind results as operation pairs identified by the same connection and operation numbers. A failed bind pair looks like this:

text
conn=19 op=0 BIND dn="uid=user1,ou=people,dc=example,dc=com" method=128 version=3
conn=19 op=0 RESULT err=49 tag=97 nentries=0 - Invalid credentials

Search historical failures with the bind line included:

bash
sudo grep -B1 'RESULT err=49' /var/log/dirsrv/slapd-ldap1/access | tail -10

The -B1 flag includes the BIND request immediately before each RESULT err=49 line so you can compare the received DN with the error.


Fix wrong password

An incorrect password or nonexistent bind DN normally returns error 49. Confirm the DN before you reset credentials, because Directory Server returns the same code for several authentication failures.

Reset the password as an administrator with dsidm:

bash
dsidm -y /root/dm.pw ldap1 account reset_password "uid=user1,ou=people,dc=example,dc=com"

Enter a new password twice when prompted. Sample output:

output
reset password for uid=user1,ou=people,dc=example,dc=com

The value must satisfy the effective password policy on the instance.

Confirm the bind with ldapwhoami:

bash
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -W

A successful bind prints the entry DN:

output
dn: uid=user1,ou=people,dc=example,dc=com

If automation still fails after a reset, check the secret file. OpenLDAP clients read the entire file contents with -y, including any unintended trailing newline:

bash
read -rsp 'LDAP password: ' LDAP_PASSWORD
printf '%s' "$LDAP_PASSWORD" > /root/user1.pw
unset LDAP_PASSWORD
chmod 600 /root/user1.pw

printf '%s' avoids the newline that echo commonly appends. Test the file:

bash
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pw

Apply only the fix supported by your bind test and access-log evidence. Resetting passwords blindly can hide the original cause and leave stale application credentials unchanged.


Fix incorrect bind DN

Applications often send a username or an outdated DN while the directory entry lives at a different distinguished name. LDAP does not compare DN strings through simple character-for-character equality; DN matching uses distinguishedNameMatch and the naming-attribute matching rules. Search as an administrator to read the exact DN. Directory queries use the ldapsearch command:

bash
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw -b "dc=example,dc=com" "(uid=user1)" uid

Sample output:

output
dn: uid=user1,ou=people,dc=example,dc=com
uid: user1

The search should return exactly one entry. No result means the DN is wrong or the entry is absent; multiple results mean the application's username search is ambiguous.

Clients frequently confuse these values:

Value Example
Username user1
Bind DN uid=user1,ou=people,dc=example,dc=com
Search base dc=example,dc=com
Search filter (uid=user1)

Typical bind DN mistakes:

  • Wrong organizational unit or suffix, such as using ou=Users when the entry is under ou=People, or using the wrong dc= suffix. A case-only difference is normally normalized; the container hierarchy and attribute values must identify the real entry.
  • Using cn= when the entry RDN is uid=
  • Entry renamed or moved without updating clients
  • Using the search base as the bind DN
  • Supplying only a username where the client must send a full DN

Copy the dn: line from the search result into every client, service account, and agreement that binds as that user. The access log BIND dn="..." line shows the DN the server received when a client still sends the wrong value.


Fix missing userPassword

A user entry can exist without a usable password attribute. Creation with dsidm user create does not always set userPassword; administrators assign it separately.

Check whether userPassword is present:

bash
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw -b "uid=user1,ou=people,dc=example,dc=com" -s base userPassword

When the attribute is absent, the search returns only the DN line or omits userPassword. Assign one with:

bash
dsidm -y /root/dm.pw ldap1 account reset_password "uid=user1,ou=people,dc=example,dc=com"

The reset creates or replaces userPassword and lets the user bind on the next attempt. The manage users and groups chapter covers the full create-and-password workflow.


Fix expired password

An expired password with no remaining grace logins returns error 49. A grace login may still permit the bind, while a mandatory-change password can allow the bind and reject later operations with error 53. For that pattern, follow fix LDAP unwilling to perform error 53.

Request policy details on bind with -e ppolicy:

bash
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -W -b "" -s base -e ppolicy namingContexts

On a healthy account with no expiration warning, the response may show only that the bind succeeded:

output
dn:
namingContexts: dc=example,dc=com

Password expiration and grace-login information appears only when the server returns a password-policy response control; a healthy account may produce no additional policy text.

When warnings or grace counts appear in the response, the account needs a password change rather than another retry with the old secret. An administrator can reset the password:

bash
dsidm -y /root/dm.pw ldap1 account reset_password "uid=user1,ou=people,dc=example,dc=com"

Users who must change password at next login should complete the change over LDAPS or StartTLS per your deployment rules. Full expiration and grace-login configuration lives in the password policy chapter.


Fix locked or inactive account

Password or account-policy state behaves differently from a simple wrong password:

Mechanism Typical bind result
Wrong password Error 49
Expired password, no grace logins left Error 49
Password-policy lockout after failed attempts Error 49 during attempts, then error 19 with Exceed password retry limit
Manual inactivation (nsAccountLock) Error 53 with account-inactivated text
Inactivity policy Error 19

Check manual activation state on the server:

bash
dsidm -y /root/dm.pw ldap1 account entry-status "uid=user1,ou=people,dc=example,dc=com"

Sample output for a healthy account:

output
Entry DN: uid=user1,ou=people,dc=example,dc=com
Entry State: activated

Entry State: activated proves the entry is not manually disabled through the account-state mechanisms checked by dsidm. It does not prove that failed-password retry counters are clear. When password-policy lockout is suspected, inspect passwordRetryCount, retryCountResetTime, and accountUnlockTime as documented in account lockout.

When Entry State is not activated, the entry was manually locked or inactivated. Unlock direct inactivation:

bash
dsidm -y /root/dm.pw ldap1 account unlock "uid=user1,ou=people,dc=example,dc=com"

Sample output:

output
Entry uid=user1,ou=people,dc=example,dc=com is unlocked

This command clears direct account inactivation such as nsAccountLock. It does not necessarily clear password-policy retry lockout. Follow the account lockout chapter when passwordRetryCount or accountUnlockTime is present. Manual inactivation outside password policy is covered in disable and inactivate user accounts.

Confirm the password is correct before you retry repeatedly during troubleshooting. Each wrong attempt can advance lockout counters on a production account.


Fix wrong LDAP server or replica

Error 49 for every user often means the client points at the wrong host, port, or protocol, or at a replica that does not yet hold the bind entry or its latest password.

Verify the URI, port, and transport match the instance you intend:

Check Example
Hostname ldap1.example.com versus localhost versus a load-balancer VIP
Port 389 plain LDAP, 636 LDAPS, or a custom instance port such as 1389
Protocol ldap:// versus ldaps:// versus StartTLS (-ZZ)

Search for the user on the same endpoint the client uses:

bash
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw -b "dc=example,dc=com" "(uid=user1)" uid

When the entry is missing on one replica but present on another, replication may be behind or the agreement may not cover that suffix. Test each server directly with the same bind DN before you change passwords.


Fix application credentials

When ldapwhoami succeeds with the DN and password the application should use, the directory bind is healthy and the remaining problem is in the application configuration.

Inspect these settings:

  • LDAP URI and TLS mode (ldap://, ldaps://, StartTLS)
  • Bind DN versus username-only login mapped locally
  • Stored password or secret file, including trailing newline or whitespace
  • Shell or config escaping that alters the secret
  • Whether the service was restarted after a password change
  • Whether the application connects to a different host or port than your manual test

Update the stored secret, restart the service, and retest login. Apache LDAP authentication and SSSD LDAP authentication cover client-specific configuration when the directory side is already correct.


Fix Directory Manager authentication

When you know the current Directory Manager password, change it online with the command below. When the password is completely lost, follow reset the Directory Manager password for the full online and offline recovery workflow. Do not use dscreate or rebuild the instance solely to recover this password.

The Directory Manager bind DN is fixed and does not include the suffix:

text
cn=Directory Manager

A wrong password returns error 49:

output
ldap_bind: Invalid credentials (49)

When you know the current Directory Manager password, change it online:

bash
dsconf -D "cn=Directory Manager" -y /root/dm.pw ldap1 directory_manager password_change

Do not use Directory Manager as an application bind account in production. Create a dedicated service entry with only the read and compare rights the application needs.


Fix replication authentication

Replication sessions bind to the consumer with the identity stored in the agreement. When that credential drifts, status output and the errors log report Invalid credentials (49). Real incidents also surface error 49 when the replication-manager password is changed but the sending agreement retains the old stored credential.

Inspect the agreement on its supplier:

bash
dsconf -y /root/dm.pw ldap1 repl-agmt get --suffix "dc=example,dc=com" ldap1-to-consumer1

Record at least:

  • nsDS5ReplicaHost
  • nsDS5ReplicaPort
  • nsDS5ReplicaBindDN
  • nsDS5ReplicaBindMethod
  • nsDS5ReplicaTransportInfo

Sample output (trimmed):

output
nsDS5ReplicaBindDN: cn=replication manager,cn=config
nsDS5ReplicaBindMethod: simple
nsDS5ReplicaHost: consumer1.example.com
nsDS5ReplicaPort: 1389
nsDS5ReplicaTransportInfo: LDAP

When the agreement uses a simple bind, test the exact agreement identity against the destination:

bash
ldapwhoami -x -H ldap://consumer1.example.com:1389 -D "cn=replication manager,cn=config" -y /root/consumer1-repl.pw

For StartTLS, add -ZZ. For LDAPS, use the configured ldaps:// URI and port. A successful bind returns:

output
dn: cn=replication manager,cn=config

Update the stored credential when it is stale. A password file passed to dsconf is an input used to update the agreement; the agreement subsequently uses the credential stored in its configuration:

bash
dsconf -y /root/dm.pw ldap1 repl-agmt set --suffix "dc=example,dc=com" --bind-dn "cn=replication manager,cn=config" --bind-passwd-file /root/consumer1-repl.pw ldap1-to-consumer1

Sample output:

output
Successfully updated agreement

Trigger and verify an incremental session:

bash
dsconf -y /root/dm.pw ldap1 repl-agmt poke --suffix "dc=example,dc=com" ldap1-to-consumer1

Sample output:

output
Agreement has been poked

Then check agreement status with dsconf repl-agmt status. Agreement creation, credential rotation, and status interpretation are in manage replication agreements. Broader replication diagnosis, including TLS and generation-ID problems, is in replication troubleshooting.


References


Frequently Asked Questions

1. What does LDAP error 49 mean in 389 Directory Server?

Error 49 means the server rejected the bind credentials. Common causes include an incorrect password, a nonexistent or outdated bind DN, an entry without a usable password, or an expired password with no remaining grace logins. Password-policy lockout and manual account inactivation can instead return related bind errors such as 19 or 53, so check the diagnostic text as well as the numeric code.

2. Why does ldapsearch return invalid credentials when the password is correct?

The bind DN may be wrong even when the uid is correct, the password file may contain a trailing newline, the password may be expired with no grace logins left, or the client may be connecting to a replica that does not contain the entry or its latest password. Confirm the full DN and endpoint before resetting the password.

3. Does error 49 always mean the password is wrong?

No. A nonexistent bind DN, an entry without userPassword, an expired password with no grace logins left, stale application secrets, and replication agreement passwords also surface as error 49 or closely related bind failures. Start from the cause table and open the matching fix section.

4. What LDAP error appears after too many failed password attempts?

Failed password attempts normally return error 49 until password-policy lockout becomes active. Subsequent binds on the tested 389 DS release return error 19 with an Exceed password retry limit diagnostic. Manual account inactivation is a separate mechanism and can return error 53.

5. How do I test a replication bind that returns error 49?

Inspect the agreement with dsconf repl-agmt get, then test its exact bind DN, host, port, and authentication method against the destination. If the password was rotated, update the stored agreement credential with dsconf repl-agmt set --bind-passwd-file, then trigger a new session and verify status.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …