Fix LDAP Unwilling to Perform Error 53 in 389 Directory Server

Fix LDAP error 53 in 389 Directory Server by reading the additional info line, then checking password policy, read-only mode, RootDN Access Control, TLS SSF, and access logs.

Published

Updated

Read time 14 min read

Reviewed byDeepak Prasad

Fix LDAP unwilling to perform error 53 in 389 Directory Server by cause — mandatory password change, read-only mode, RootDN restrictions, and minimum SSF
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 error 53: password policy, read-only mode, RootDN access control, TLS SSF, and access logs. Does not cover unrelated LDAP error codes.
Related guides Install 389 Directory Server
dsconf commands
ACI examples
Fix LDAP invalid credentials error 49
Fix LDAP error 50 insufficient access

LDAP unwilling to perform error 53 means 389 Directory Server understood the request but refused it because of configuration, policy, or server state. Clients usually print:

text
ldap_modify: Server is unwilling to perform (53)

The same code appears on bind, search, add, delete, and extended operations:

text
ldap_search: Server is unwilling to perform (53)
text
ldap_bind: Server is unwilling to perform (53)

389 DS often adds a more specific line:

text
additional info: Server is read-only

RFC 4511 defines result code 53 as unwillingToPerform. Read the diagnostic text alongside the number. The additional info line is the main diagnostic path in this guide.

Result Meaning
Error 49 Authentication failed
Error 50 The authorization identity lacks sufficient access rights after ACI evaluation
Error 53 The server refuses the operation because of policy, mode, or another restriction
Error 65 The entry violates schema rules

Error 53 is not an ACI authorization failure. When the message names a missing attribute right, use fix LDAP insufficient access error 50 instead of editing ACIs here. When the bind fails with error 49, use fix LDAP invalid credentials error 49.

Use the cause table below to jump to the fix that matches your situation. Password-policy design, read-only databases, RootDN Access Control, and TLS enforcement stay in the linked chapters.

IMPORTANT
This article covers LDAP result code 53 and closely related refusals in 389 Directory Server. It does not cover Microsoft Active Directory diagnostic subcodes, TLS handshake failures before any LDAP result, or schema violations that return error 65.

Examples use instance ldap1 on ldap1.example.com:389 with suffix dc=example,dc=com and users under ou=people. LDAPS examples use /etc/dirsrv/slapd-ldap1/ca.crt as LDAPTLS_CACERT. Create matching test entries before you follow the exercises, or substitute your own lab accounts.

Before you change global settings in this guide, record the current values and restore them when you finish. Do not assume the lab default is off or 0. Each cleanup section uses shell variables—replace the example assignments with the values you captured before that exercise.

bash
dsconf ldap1 pwpolicy get | grep -i passwordmustchange
bash
dsconf ldap1 config get nsslapd-readonly nsslapd-require-secure-binds nsslapd-minssf nsslapd-minssf-exclude-rootdse
bash
dsconf ldap1 plugin root-dn show
bash
dsconf ldap1 backend suffix get userroot | grep nsslapd-readonly

Causes and fixes at a glance

Additional information or behaviour Likely cause Fix
Password must be changed Administrator reset password; user must replace it Fix mandatory password change
Server is read-only Instance configured read-only Fix read-only instance or database
database is read-only Backend suffix in read-only mode Fix read-only instance or database
RootDN access control violation RootDN Access Control plug-in blocked the bind Fix RootDN Access Control restrictions
Minimum SSF not met Connection below nsslapd-minssf Fix TLS and minimum SSF requirements
Operation requires a secure connection (error 13) nsslapd-require-secure-binds rejects plain simple binds Fix TLS and minimum SSF requirements
Search works but writes return error 53 Instance or backend read-only mode Fix read-only instance or database
Write returns a referral Client reached a read-only consumer with a supplier referral Test the supplier directly; see read-only databases and instances
Account inactivated message Manual account lock disable and inactivate user accounts
Only one task or operation fails Plug-in, backend, or operation-specific restriction Diagnose operation-specific refusals
No useful client message Detailed reason only in logs Inspect 389 Directory Server logs

Reproduce the exact rejected operation

Confirm the authenticated identity with the ldapwhoami command before you change server policy:

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

Sample output:

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

Repeat the exact search, modify, add, delete, password change, or extended operation that failed. A write test as Directory Manager looks like this. Save /tmp/desc-test.ldif:

ldif
dn: uid=user1,ou=people,dc=example,dc=com
changetype: modify
replace: description
description: Error 53 test

Run the modify with the ldapmodify command:

bash
ldapmodify -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw -f /tmp/desc-test.ldif

When the server refuses the operation, the full client output matters:

output
ldap_modify: Server is unwilling to perform (53)
	additional info: Server is read-only

Do not troubleshoot from the numeric code alone when additional info names the restriction. After you remove the restriction on the endpoint that refused the write, the same modify succeeds:

output
modifying entry "uid=user1,ou=people,dc=example,dc=com"

Inspect 389 Directory Server logs

Reproduce the failure, then locate the denied operation:

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

Sample output (trimmed):

output
conn=85 op=1 MOD dn="uid=user1,ou=people,dc=example,dc=com"
conn=85 op=1 RESULT err=53 tag=103 nentries=0

The line before RESULT err=53 is normally the denied operation request, not the earlier bind result. Inspect the full connection using the conn= value from that pair:

bash
sudo grep 'conn=85 ' /var/log/dirsrv/slapd-ldap1/access

Sample output (trimmed):

output
conn=85 op=0 BIND dn="cn=Directory Manager" method=128 version=3
conn=85 op=0 RESULT err=0 tag=97 nentries=0 dn="cn=directory manager"
conn=85 op=1 MOD dn="uid=user1,ou=people,dc=example,dc=com"
conn=85 op=1 RESULT err=53 tag=103 nentries=0

err=0 on op=0 is the successful bind. err=53 on op=1 is the refused modify on the same connection. When several clients connect at once, match conn= and op= numbers rather than relying on wall-clock time alone.

Mandatory password change produces a different pattern on its own connection. After a successful bind, the next operation on the same session is refused:

bash
sudo grep 'conn=90 ' /var/log/dirsrv/slapd-ldap1/access | tail -10

Sample output (trimmed):

output
conn=90 op=0 BIND dn="uid=user2,ou=people,dc=example,dc=com" method=128 version=3
conn=90 op=0 RESULT err=0 tag=97 nentries=0 dn="uid=user2,ou=people,dc=example,dc=com"
conn=90 op=1 UNPROCESSED OPERATION - need new password
conn=90 op=1 RESULT err=53 tag=101 nentries=0

Review /var/log/dirsrv/slapd-ldap1/errors on the same timestamp when the client message is thin. Authentication-related refusals can also appear in /var/log/dirsrv/slapd-ldap1/security.


Fix mandatory password change

The typical sequence is:

  1. An administrator resets the password with passwordmustchange enabled.
  2. The bind succeeds.
  3. Searches and other operations return error 53.
  4. Only the password-change operation is allowed until the user replaces the credential.

Record the current global flag before you change it:

bash
dsconf ldap1 pwpolicy get | grep -i passwordmustchange

Enable the flag for the lab exercise:

bash
dsconf ldap1 pwpolicy set --pwdmustchange on

Confirm the effective value:

bash
dsconf ldap1 pwpolicy get | grep -i passwordmustchange

Sample output:

output
passwordmustchange: on

Reset user2 as Directory Manager. Enter a temporary password when prompted:

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

Request password-policy details on bind with the ldapsearch command. Enter the temporary password when prompted:

bash
ldapsearch -LLL -x -H ldap://ldap1.example.com:389 -D "uid=user2,ou=people,dc=example,dc=com" -W -b "uid=user2,ou=people,dc=example,dc=com" -s base -e ppolicy "(objectClass=*)" cn

Sample output:

output
ldap_bind: Success (0); Password must be changed
ldap_search: Server is unwilling to perform (53)
# PasswordExpired control

The bind succeeded, but the search was refused until the password is replaced.

Change the password over LDAPS after you configure the TLS-protected self-service rule in self-service password and profile ACIs. Use prompts for the old and new passwords:

bash
LDAPTLS_CACERT=/etc/dirsrv/slapd-ldap1/ca.crt ldappasswd -x -H ldaps://ldap1.example.com:636 -D "uid=user2,ou=people,dc=example,dc=com" -W -S

Confirm normal access resumes:

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

Sample output:

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

Restore the value you recorded before the exercise:

bash
ORIGINAL_PWDMUSTCHANGE=off

Replace the assignment with the value from dsconf ldap1 pwpolicy get | grep -i passwordmustchange, then run:

bash
dsconf ldap1 pwpolicy set --pwdmustchange "$ORIGINAL_PWDMUSTCHANGE"
bash
dsconf ldap1 pwpolicy get | grep -i passwordmustchange

Full expiration, grace-login, and temporary-password policy design lives in the password policy chapter.


Fix read-only instance or database

A read-only server normally allows searches but refuses modifications:

text
ldap_modify: Server is unwilling to perform (53)
	additional info: Server is read-only

The exact diagnostic text can vary by release. On Rocky Linux 10.2 during disposable testing, backend read-only mode also reported database is read-only. Use dsconf ldap1 config get nsslapd-readonly and dsconf ldap1 backend suffix get to distinguish instance-wide mode from backend mode rather than relying only on capitalization or wording in additional info.

On the shared replicated ldap1 instance used by the course, inspect the current state for diagnosis only:

bash
dsconf ldap1 config get nsslapd-readonly

Sample output when the instance is writable:

output
nsslapd-readonly: off

Do not enable instance-wide read-only mode on the replicated ldap1 instance. The setting disables replication, and an instance cannot be restarted while read-only or started again after being stopped in that state until nsslapd-readonly is corrected in dse.ldif. Reproduce instance-wide and backend read-only behaviour on a disposable non-replicated instance such as readonly-lab, or complete the hands-on exercises in read-only databases and instances.

Backend read-only mode blocks writes on one suffix while the rest of the instance may still accept them. Inspect the current backend setting without changing the replicated userroot database:

bash
dsconf ldap1 backend suffix get userroot | grep nsslapd-readonly

Sample output:

output
nsslapd-readonly: off

Do not enable backend read-only mode on the replicated userroot database used by the replication chapters. Enabling backend read-only mode disables replication on that database.

On Rocky Linux 10.2 during disposable testing on a non-replicated backend, a modify against a read-only suffix returned:

output
ldap_modify: Server is unwilling to perform (53)
	additional info: database is read-only

Official RHDS examples often show Server is read-only for both instance-level and database-level tests. Treat the client message as a hint and confirm the mode with dsconf.

If the client reached a consumer, check whether it returned a referral rather than error 53. Test the supplier directly before changing read-only settings. Full backend and replica read-only workflows are in read-only databases and instances.


Fix RootDN Access Control restrictions

This cause normally affects cn=Directory Manager binds:

text
ldap_bind: Server is unwilling to perform (53)
	additional info: RootDN access control violation

Record the current plug-in configuration before you change it:

bash
dsconf ldap1 plugin root-dn show
IMPORTANT
Run the configuration commands from the directory-server console or another administration path that the deny rule will not block. Keep that session open until you verify the test and restore the original configuration. Disabling the plug-in does not necessarily erase stored IP or host rules. Restore the recorded RootDN plug-in settings rather than assuming the previous state was empty. If every remote administration path is blocked and the Directory Manager password is also lost, recover from the host console through reset the Directory Manager password before you adjust plug-in rules.

Enable the plug-in and deny the client IP for the lab test. Replace 10.0.2.15 with the address your client uses to reach the server:

bash
dsconf ldap1 plugin root-dn enable
bash
dsconf ldap1 plugin root-dn set --deny-ip="10.0.2.15"

Restart the instance so the plug-in evaluates the new rule:

bash
dsctl ldap1 restart

Retry the Directory Manager bind:

bash
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw

Sample output:

output
ldap_bind: Server is unwilling to perform (53)
	additional info: RootDN access control violation

Do not reset the Directory Manager password when the message explicitly reports a RootDN access-control violation.

Restore the RootDN Access Control plug-in to its recorded state. If it was disabled before the exercise, disable it again. If it was already enabled, restore its previous IP, host, day, and time rules and leave it enabled. Restart the instance after restoring the configuration. Overly restrictive rules can prevent Directory Manager from performing administrative recovery, so keep an administration path open until the original policy is back in place.

Run this cleanup only when the plug-in was disabled before the exercise:

bash
dsconf ldap1 plugin root-dn disable
bash
dsctl ldap1 restart

When the plug-in was already enabled, use dsconf ldap1 plugin root-dn set to restore the allow, deny, and time rules you recorded from dsconf ldap1 plugin root-dn show, then restart the instance.

Review allowed hosts, IP ranges, and time windows with dsconf ldap1 plugin root-dn set --help. Complete plug-in configuration is documented in the product guides linked in References.


Fix TLS and minimum SSF requirements

Some refusals are security restrictions rather than password or read-only policy.

nsslapd-require-secure-binds

Record the current value before you change it:

bash
dsconf ldap1 config get nsslapd-require-secure-binds

Enable secure simple binds:

bash
dsconf ldap1 config replace nsslapd-require-secure-binds=on

Sample output:

output
Successfully replaced value(s) for 'nsslapd-require-secure-binds': 'on'

Restart the instance so the policy takes effect:

bash
dsctl ldap1 restart
IMPORTANT
Do not enable this test on a shared replication or chaining lab until every server-to-server connection is already configured for StartTLS, LDAPS, or another secure authentication method. The restriction also affects authenticated server-to-server connections, including replication, chaining, and synchronization.

Run the plain-LDAP failure test after the restart:

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

Sample output:

output
ldap_bind: Confidentiality required (13)
	additional info: Operation requires a secure connection

Result code 13 is related to the same policy. Retry over StartTLS:

bash
LDAPTLS_CACERT=/etc/dirsrv/slapd-ldap1/ca.crt ldapwhoami -x -ZZ -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pw

Restore the value you recorded before the exercise:

bash
ORIGINAL_SECURE_BINDS=off

Replace the assignment with the value from dsconf ldap1 config get nsslapd-require-secure-binds, then run:

bash
dsconf ldap1 config replace "nsslapd-require-secure-binds=${ORIGINAL_SECURE_BINDS}"
bash
dsctl ldap1 restart

Confirm the effective value:

bash
dsconf ldap1 config get nsslapd-require-secure-binds

nsslapd-minssf

Record the current SSF settings before you change them:

bash
dsconf ldap1 config get nsslapd-minssf nsslapd-minssf-exclude-rootdse nsslapd-localssf

Minimum Security Strength Factor rejects operations on connections that are not sufficiently protected:

bash
dsconf ldap1 config replace nsslapd-minssf=128 nsslapd-minssf-exclude-rootdse=on
bash
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pw

Sample output:

output
ldap_parse_result: Server is unwilling to perform (53)
	additional info: Minimum SSF not met.

StartTLS or LDAPS satisfies the threshold when configured correctly. After you raise nsslapd-minssf, use LDAPS or required StartTLS for dsconf administration as well. Use LDAPI only when the configured nsslapd-localssf meets the new minimum. Full TLS and SSF design is in enforce TLS and secure binds.

Reset the recorded values over an explicitly protected connection once plain ldap:// administration is rejected:

bash
ORIGINAL_MINSSF=0
ORIGINAL_EXCLUDE_ROOTDSE=off

Replace both assignments with the values from dsconf ldap1 config get nsslapd-minssf nsslapd-minssf-exclude-rootdse, then run:

bash
LDAPTLS_CACERT=/etc/dirsrv/slapd-ldap1/ca.crt dsconf -D "cn=Directory Manager" -y /root/dm.pw ldaps://ldap1.example.com:636 config replace "nsslapd-minssf=${ORIGINAL_MINSSF}" "nsslapd-minssf-exclude-rootdse=${ORIGINAL_EXCLUDE_ROOTDSE}"

Confirm the effective values:

bash
dsconf ldap1 config get nsslapd-minssf nsslapd-minssf-exclude-rootdse

If you can no longer reach the instance over LDAPS or StartTLS, stop the instance, edit nsslapd-minssf and nsslapd-minssf-exclude-rootdse in /etc/dirsrv/slapd-ldap1/dse.ldif, and then start the instance. Never edit the live dse.ldif while the server is running.


Diagnose operation-specific refusals

When the earlier causes do not apply, identify the exact operation the server refused. Common 389 DS scenarios include:

  • Attempting an operation while a mandatory password change is pending
  • Writing to a read-only consumer or chained backend
  • Running a task that the backend or plug-in does not support on a replicated suffix
  • Sending a critical control that the server cannot or will not process
  • Performing writes while maintenance or read-only state is active

The errors log usually carries a more specific explanation than the LDAP client displays. Keep replication, chaining, alias, password-policy quality rules, and plug-in fixes in their operational chapters rather than duplicating them here.


Verify the fix

Repeat the exact operation after applying the fix. A successful modify prints:

output
modifying entry "uid=user1,ou=people,dc=example,dc=com"

The retest creates a new LDAP connection, so it receives a new conn= value. The earlier failed conn= record is not updated to err=0. Inspect the latest access-log entries instead:

bash
sudo tail -20 /var/log/dirsrv/slapd-ldap1/access

Find the new MOD, ADD, BIND, or search request from your retest and confirm that its corresponding RESULT line on the same new conn= and op= values reports err=0.

Retest the original application, SSSD client, password-change form, or script against the same host and port you repaired. When the failure was intermittent, test every replica directly instead of relying on a single load-balanced endpoint.


Troubleshooting

Symptom Likely cause Check
Bind succeeds but search returns 53 Password must be changed ldapsearch with -e ppolicy
All writes return 53 Instance or database read-only nsslapd-readonly and backend suffix state
Write returns a referral Client reached a read-only consumer with a supplier referral Test the supplier directly
Writes fail on only one server Client reached a consumer or wrong replica Test each host directly; check for referrals
Directory Manager bind returns 53 RootDN Access Control restriction Client IP, hostname, day, and time rules
Plain LDAP fails but StartTLS works Secure-bind or SSF requirement nsslapd-require-secure-binds and nsslapd-minssf
One maintenance task returns 53 Unsupported backend or plug-in operation Errors log on the same timestamp
Search works but modify fails Read-only state or operation restriction Additional info line and access log
Application fails but CLI works Different endpoint or operation Compare URI, bind DN, and access log
Client shows only error 53 Thin client diagnostics Access, errors, and security logs
Result is error 50 instead ACI authorization failure Error 50 troubleshooting guide
Result is error 49 instead Bind credentials rejected Error 49 troubleshooting guide

References


Summary

LDAP error 53 in 389 Directory Server means the server refused an operation because of policy or state, not because ACIs denied an otherwise permitted action. Reproduce the exact command, read the additional info line, grep err=53 in the access log, and open the matching fix section for password change, read-only mode, RootDN Access Control, or SSF requirements. Distinguish error 53 from error 49 and error 50 before you reset passwords or edit ACIs.


Frequently Asked Questions

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

Error 53 means the server understood the request but refuses to perform it because of configuration, policy, or server state. The additional info line often names the restriction, such as Password must be changed, Server is read-only, RootDN access control violation, or Minimum SSF not met.

2. What is the difference between LDAP error 50 and error 53?

Error 50 is an authorization failure after ACI evaluation. Error 53 is a broader refusal based on password policy, read-only mode, RootDN Access Control, SSF requirements, or other server restrictions. If the message names a missing attribute right, use the error 50 guide instead of changing ACIs here.

3. Why does ldapsearch return error 53 after a successful bind?

A bind can succeed while password policy still blocks other operations. Mandatory password change is the common case: the bind authenticates, but searches and modifies return error 53 until the user replaces the password. Request the password-policy control to confirm.

4. Does error 53 mean the LDAP server is read-only?

Instance-wide or backend read-only settings can return error 53 on writes while searches may still work. A read-only replication consumer may instead return a referral to a writable supplier when the replicated suffix has a referral configured. Read the additional info line and check dsconf readonly settings on the endpoint you reached.

5. How do I find the real reason when the client only shows error 53?

Repeat the exact operation, read the additional info text, grep err=53 in the access log, and review the errors log on the same timestamp. Security logs can also record authentication-related refusals.
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 …