| 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:
ldap_modify: Server is unwilling to perform (53)The same code appears on bind, search, add, delete, and extended operations:
ldap_search: Server is unwilling to perform (53)ldap_bind: Server is unwilling to perform (53)389 DS often adds a more specific line:
additional info: Server is read-onlyRFC 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.
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.
dsconf ldap1 pwpolicy get | grep -i passwordmustchangedsconf ldap1 config get nsslapd-readonly nsslapd-require-secure-binds nsslapd-minssf nsslapd-minssf-exclude-rootdsedsconf ldap1 plugin root-dn showdsconf ldap1 backend suffix get userroot | grep nsslapd-readonlyCauses 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:
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample output:
dn: uid=user1,ou=people,dc=example,dc=comRepeat 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:
dn: uid=user1,ou=people,dc=example,dc=com
changetype: modify
replace: description
description: Error 53 testRun the modify with the ldapmodify command:
ldapmodify -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw -f /tmp/desc-test.ldifWhen the server refuses the operation, the full client output matters:
ldap_modify: Server is unwilling to perform (53)
additional info: Server is read-onlyDo 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:
modifying entry "uid=user1,ou=people,dc=example,dc=com"Inspect 389 Directory Server logs
Reproduce the failure, then locate the denied operation:
sudo grep -B1 'RESULT err=53' /var/log/dirsrv/slapd-ldap1/access | tail -10Sample output (trimmed):
conn=85 op=1 MOD dn="uid=user1,ou=people,dc=example,dc=com"
conn=85 op=1 RESULT err=53 tag=103 nentries=0The 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:
sudo grep 'conn=85 ' /var/log/dirsrv/slapd-ldap1/accessSample output (trimmed):
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=0err=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:
sudo grep 'conn=90 ' /var/log/dirsrv/slapd-ldap1/access | tail -10Sample output (trimmed):
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=0Review /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:
- An administrator resets the password with
passwordmustchangeenabled. - The bind succeeds.
- Searches and other operations return error 53.
- Only the password-change operation is allowed until the user replaces the credential.
Record the current global flag before you change it:
dsconf ldap1 pwpolicy get | grep -i passwordmustchangeEnable the flag for the lab exercise:
dsconf ldap1 pwpolicy set --pwdmustchange onConfirm the effective value:
dsconf ldap1 pwpolicy get | grep -i passwordmustchangeSample output:
passwordmustchange: onReset user2 as Directory Manager. Enter a temporary password when prompted:
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:
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=*)" cnSample output:
ldap_bind: Success (0); Password must be changed
ldap_search: Server is unwilling to perform (53)
# PasswordExpired controlThe 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:
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 -SConfirm normal access resumes:
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user2,ou=people,dc=example,dc=com" -WSample output:
dn: uid=user2,ou=people,dc=example,dc=comRestore the value you recorded before the exercise:
ORIGINAL_PWDMUSTCHANGE=offReplace the assignment with the value from dsconf ldap1 pwpolicy get | grep -i passwordmustchange, then run:
dsconf ldap1 pwpolicy set --pwdmustchange "$ORIGINAL_PWDMUSTCHANGE"dsconf ldap1 pwpolicy get | grep -i passwordmustchangeFull 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:
ldap_modify: Server is unwilling to perform (53)
additional info: Server is read-onlyThe 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:
dsconf ldap1 config get nsslapd-readonlySample output when the instance is writable:
nsslapd-readonly: offDo 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:
dsconf ldap1 backend suffix get userroot | grep nsslapd-readonlySample output:
nsslapd-readonly: offDo 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:
ldap_modify: Server is unwilling to perform (53)
additional info: database is read-onlyOfficial 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:
ldap_bind: Server is unwilling to perform (53)
additional info: RootDN access control violationRecord the current plug-in configuration before you change it:
dsconf ldap1 plugin root-dn showEnable 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:
dsconf ldap1 plugin root-dn enabledsconf ldap1 plugin root-dn set --deny-ip="10.0.2.15"Restart the instance so the plug-in evaluates the new rule:
dsctl ldap1 restartRetry the Directory Manager bind:
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pwSample output:
ldap_bind: Server is unwilling to perform (53)
additional info: RootDN access control violationDo 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:
dsconf ldap1 plugin root-dn disabledsctl ldap1 restartWhen 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:
dsconf ldap1 config get nsslapd-require-secure-bindsEnable secure simple binds:
dsconf ldap1 config replace nsslapd-require-secure-binds=onSample output:
Successfully replaced value(s) for 'nsslapd-require-secure-binds': 'on'Restart the instance so the policy takes effect:
dsctl ldap1 restartRun the plain-LDAP failure test after the restart:
ldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample output:
ldap_bind: Confidentiality required (13)
additional info: Operation requires a secure connectionResult code 13 is related to the same policy. Retry over StartTLS:
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.pwRestore the value you recorded before the exercise:
ORIGINAL_SECURE_BINDS=offReplace the assignment with the value from dsconf ldap1 config get nsslapd-require-secure-binds, then run:
dsconf ldap1 config replace "nsslapd-require-secure-binds=${ORIGINAL_SECURE_BINDS}"dsctl ldap1 restartConfirm the effective value:
dsconf ldap1 config get nsslapd-require-secure-bindsnsslapd-minssf
Record the current SSF settings before you change them:
dsconf ldap1 config get nsslapd-minssf nsslapd-minssf-exclude-rootdse nsslapd-localssfMinimum Security Strength Factor rejects operations on connections that are not sufficiently protected:
dsconf ldap1 config replace nsslapd-minssf=128 nsslapd-minssf-exclude-rootdse=onldapwhoami -x -H ldap://ldap1.example.com:389 -D "uid=user1,ou=people,dc=example,dc=com" -y /root/user1.pwSample 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:
ORIGINAL_MINSSF=0
ORIGINAL_EXCLUDE_ROOTDSE=offReplace both assignments with the values from dsconf ldap1 config get nsslapd-minssf nsslapd-minssf-exclude-rootdse, then run:
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:
dsconf ldap1 config get nsslapd-minssf nsslapd-minssf-exclude-rootdseIf 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:
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:
sudo tail -20 /var/log/dirsrv/slapd-ldap1/accessFind 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
- RFC 4511 — LDAP result codes
- 389 Directory Server documentation
- Red Hat Directory Server 13 — Managing access control
- Red Hat Directory Server 13 — Log files reference
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.

