Diagnosing directory problems: reading slapd logs and debug levels, common failures in binds, searches, replication, and performance, and a systematic troubleshooting methodology.

Sooner or later the directory misbehaves: a bind fails, a search is slow, replication stalls. Episode 27 teaches troubleshooting as a method, not a bag of tricks. You'll learn to read the logs at the right debug level, recognize the most common failure patterns, and follow a systematic path from symptom to cause.
Before touching commands, follow a discipline:
Logs are the primary source of truth. Levels were covered in episode 18; here's how to use them for diagnosis:
| Level | Diagnostic value |
|---|---|
stats | operations, connections, bind results — the daily view |
conns | connection lifecycle — connectivity problems |
filter | the exact search filters arriving — query problems |
acl | why an access was denied — authorization problems |
sync | replication events — replication problems |
Enable a level temporarily, reproduce the failure, then read the log:
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: conns,filter,acl,statsWhen the incident is over, return to stats. Debug levels are for diagnosis, not for production running — high levels crush throughput.
Important
stats2, packets, trace, and the highest debug levels are extremely noisy and slow the server. Never leave a high debug level running in production "just in case" — you'll diagnose the slowdown you caused before the original problem.
| Symptom | Likely cause | Fix |
|---|---|---|
| result 49 (invalid credentials) | wrong password, or locked account (episode 12) | check credentials; check pwdAccountLockedTime |
| result 49 + "no such user" | account doesn't exist, or wrong search base | verify the DN; check the base |
| result 50 (insufficient access) | ACL denies the bind | review the ACLs in cn=config |
| result 13 (confidentiality required) | olcSecurity: ssf blocks a plain connection | connect with StartTLS/LDAPS |
| "connection refused" | firewall, or slapd down | systemctl status slapd; nc -vz host 389 |
| result 91 (connect error) | network unreachable, DNS wrong | ping; dig; check URI config |
Test binds layer by layer:
systemctl status slapd
nc -vz ldap.example.com 389
ldapwhoami -x -D uid=budi,ou=people,dc=example,dc=com -w wrongpass
ldapwhoami -x -Y EXTERNAL -H ldapi:///| Symptom | Likely cause | Fix |
|---|---|---|
| empty result | wrong base, wrong filter | test the filter in ldapsearch step by step |
| result 4 (size limit exceeded) | olcSizeLimit too small for the query | raise the limit or narrow the filter |
| slow search | missing index (episode 14) | add eq/sub index, slapindex |
| partial result | scope wrong (base vs one vs sub) | check -s base/one/sub |
| result 32 (no such object) | base DN doesn't exist on this server | ldapsearch -b dc=example,dc=com (objectClass=*) |
| result 11 (admin limit) | server-imposed limits hit | check olcLimits and olcTimeLimit |
The systematic search test:
ldapsearch -x -b dc=example,dc=com "(objectClass=*)" dn
ldapsearch -x -b ou=people,dc=example,dc=com "(objectClass=inetOrgPerson)" dn
ldapsearch -x -b ou=people,dc=example,dc=com "(uid=budi)" dnEach step narrows where the filter or base is wrong.
| Symptom | Likely cause | Fix |
|---|---|---|
lagging contextCSN | network, credentials, or provider overload | compare contextCSN on both sides; check the bind account |
| result 49 in replication bind | cn=replicator password changed | update olcSyncrepl credentials |
| no sync events in logs | olcSyncrepl not applied, or rid conflict | verify the config with slaptest -u |
| inconsistent data | conflict resolution by contextCSN | identify which node won; decide policy |
| "connection lost" loops | firewall, or provider restarted | check connectivity; the retry value handles reconnects |
ldapsearch -x -H ldap://ldap01.example.com -b dc=example,dc=com contextCSN
ldapsearch -x -H ldap://ldap02.example.com -b dc=example,dc=com contextCSN
grep -i syncrepl /var/log/slapd/slapd.log | tail -20time ldapsearch against the same query with -b a tiny base.cn=Monitor show? monitorOpCompleted per operation type tells you if searches dominate.olcDbMaxReaders (episode 25).olcDbMaxSize reached; the data file is full. This is the emergency case from episode 25.{SSHA512} costs more than {SSHA}; measure if it matters.top -b -n1 | head -20
ldapsearch -x -D cn=admin,dc=example,dc=com -W \
-b cn=Connections,cn=Monitor monitorConnectionTotalWhen something is wrong, run this order:
systemctl status slapd — is the server alive?slaptest -u — is the configuration valid?ldapsearch -b dc=example,dc=com "(objectClass=*)" dn — can you read at all?olcLogLevel — reproduce the failure and read the log.ldapsearch from the server itself, then from a client.Note
The debug level -d flag on slapd -d 256 (which equals stats) is the offline twin of olcLogLevel — useful for a fresh manual start, never for a running production server.
In this episode 27 you learned systematic troubleshooting: the reproduce-isolate-log discipline; reading slapd logs at the right level; the common bind, search, replication, and performance failures with their causes and fixes; and a six-step diagnostic flow from service status to log reading to isolated testing.
Key takeaways:
conns,filter,acl,stats covers most incidents.slaptest -u catches config errors early — before they become runtime mysteries.In the next episode, episode 28, we design for the long run: schema design best practices — DIT design, custom schema with OID allocation, normalization, and safe migration patterns.