Fix LDAP Object Class Violation Error 65 in 389 Directory Server

Fix LDAP error 65 in 389 Directory Server by reading the additional info line, then checking object class MUST and MAY rules, entry state, custom schema, plug-ins, and replica schema parity.

Published

Updated

Read time 12 min read

Reviewed byDeepak Prasad

Fix LDAP object class violation error 65 in 389 Directory Server — missing MUST attributes, disallowed attributes, object class changes, and schema consistency
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 65: object class rules, entry state, custom schema, plug-ins, and replica schema parity. Does not cover unrelated LDAP error codes.
Related guides Install 389 Directory Server
Create custom schema
Export and import LDIF
dsidm commands
Manage users and groups

LDAP object class violation error 65 means 389 Directory Server rejected an add, modify, import, or plug-in update because the resulting entry would not comply with its object class definitions. Clients usually print:

text
ldap_add: Object class violation (65)

The same code appears on modify and some extended operations:

text
ldap_modify: Object class violation (65)

389 DS often adds a specific line:

text
additional info: missing attribute "sn" required by object class "person"

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

Result Meaning
Error 17 Attribute type is undefined
Error 21 Attribute value has invalid syntax
Error 65 Entry violates object-class or schema rules
Error 69 Structural object-class modification is prohibited

Error 65 is not an authorization failure. When the message names insufficient access, use fix LDAP insufficient access error 50 instead of editing object classes. When the server refuses an operation because of policy or state, use fix LDAP unwilling to perform error 53.

Use the diagnosis table below to jump to the fix that matches your situation. Custom schema design, bulk schema repair, and MemberOf configuration stay in the linked chapters.

IMPORTANT
This article covers LDAP result code 65 and closely related schema-validation failures in 389 Directory Server. It does not cover Microsoft Active Directory diagnostic subcodes, undefined attribute types that return error 17, or syntax errors that return error 21.

Examples use instance ldap1 on ldap1.example.com:389 with suffix dc=example,dc=com and users under ou=people. Create matching test entries before you follow the exercises, or substitute your own lab accounts.


Causes and fixes at a glance

Additional information or behaviour Likely cause Fix
missing attributerequired by object class MUST attribute absent from the entry Fix missing required attributes
attributenot allowed Attribute is not permitted as MUST or MAY by any assigned or inherited object class Fix disallowed attributes
Failure after removing an object class Unsupported attributes remain on the entry Fix disallowed attributes
Failure after adding an object class New class MUST attributes were not added Fix missing required attributes
Structural object-class conflict Assigned structural classes do not form one inheritance chain Fix disallowed attributes
MemberOf or plug-in modify fails with 65 Target entry does not permit generated attribute Check plug-ins, imports, and custom schema
LDIF import rejects one entry Imported entry does not match local schema Check plug-ins, imports, and custom schema
Same change works on one replica only Schema definitions differ between servers Check schema consistency across replicas
undefined attribute type Attribute definition is missing Confirm the attribute exists; see custom schema
Unknown or unrecognized object class Object-class definition is missing locally Compare schema on the affected server
No useful client message Detailed reason only in logs Grep err=65 in the access log

Reproduce the failed LDAP operation

Repeat the exact ldapadd or ldapmodify command, LDIF import line, or application write that failed. Save the LDIF exactly as the client sent it.

A missing MUST attribute produces a clear add failure. Save /tmp/err65-missing-sn.ldif:

ldif
dn: uid=err65test,ou=people,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: err65test
cn: Error 65 Test

Run the add as Directory Manager:

bash
ldapadd -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw -f /tmp/err65-missing-sn.ldif

Sample output:

output
ldap_add: Object class violation (65)
	additional info: missing attribute "sn" required by object class "person"

adding new entry "uid=err65test,ou=people,dc=example,dc=com"

The additional info line names the missing attribute and the object class that requires it. Do not troubleshoot from the numeric code alone when the server provides that detail.

Locate the denied operation in the access log:

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

Sample output (trimmed):

output
conn=2 op=2 ADD dn="uid=err65test,ou=people,dc=example,dc=com"
conn=2 op=2 RESULT err=65 tag=105 nentries=0 - missing attribute "sn" required by object class "person"

The access log often repeats the same explanation after RESULT err=65.


Inspect object classes and query schema definitions

Schema validation applies to the complete resulting entry, not only the attribute named in the modify.

For an existing entry, list its object classes and attributes with the ldapsearch command:

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 "(objectClass=*)" "*"

Compare the object classes assigned to the entry, the attributes currently stored, the attributes being added or removed, and the final entry state after the requested modification. To retrieve only the object-class list, request objectClass instead of "*":

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 "(objectClass=*)" objectClass

Query the relevant object class definition, including inherited MUST and MAY attributes from superior classes:

bash
dsconf ldap1 schema objectclasses query --include-sup inetOrgPerson

Sample output (trimmed):

output
( 2.16.840.1.113730.3.2.2 NAME 'inetOrgPerson' SUP organizationalPerson STRUCTURAL MUST ( cn $ sn ) MAY ( audio $ businessCategory $ carLicense $ departmentNumber $ description $ destinationIndicator $ displayName $ employeeNumber $ employeeType $ facsimileTelephoneNumber $ givenName $ homePhone $ homePostalAddress $ initials $ internationalISDNNumber $ jpegPhoto $ l $ labeledURI $ mail $ manager $ mobile $ o $ ou $ pager $ photo $ physicalDeliveryOfficeName $ postOfficeBox $ postalAddress $ postalCode $ preferredDeliveryMethod $ preferredLanguage $ registeredAddress $ roomNumber $ secretary $ seeAlso $ st $ street $ telephoneNumber $ teletexTerminalIdentifier $ telexNumber $ title $ uid $ userCertificate $ userPKCS12 $ userPassword $ userSMIMECertificate $ x121Address $ x500UniqueIdentifier ) X-ORIGIN 'RFC 2798' )

The MUST ( cn $ sn ) list shows both attributes required on the final entry. With --include-sup, dsconf includes inherited attributes from superior classes, so the displayed effective MUST and MAY lists can be broader than the class's standalone schema definition.

Schema element Meaning
MUST Attribute must exist on the entry
MAY Attribute is allowed but optional
SUP Superior object class whose rules are inherited
STRUCTURAL Defines the primary entry type
AUXILIARY Adds additional permitted attributes
ABSTRACT Used only through derived object classes

Review /var/log/dirsrv/slapd-ldap1/errors on the same timestamp when the client message is thin.


Fix missing required attributes

For the earlier inetOrgPerson example, add the missing surname. Save /tmp/err65-fixed.ldif:

ldif
dn: uid=err65test,ou=people,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: err65test
cn: Error 65 Test
sn: Test

Run the corrected add:

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

Sample output:

output
adding new entry "uid=err65test,ou=people,dc=example,dc=com"

When you add any object class, include every newly required MUST attribute in the same LDAP modify request. Do not remove an object class merely to avoid supplying data that is fundamental to the intended entry type.


Fix disallowed attributes and object class changes

A modify can fail when an attribute is not permitted by any assigned object class. Save /tmp/err65-bad-attr.ldif:

ldif
dn: uid=user1,ou=people,dc=example,dc=com
changetype: modify
add: member
member: cn=test,ou=groups,dc=example,dc=com

Run the modify:

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

Sample output:

output
ldap_modify: Object class violation (65)
	additional info: attribute "member" not allowed
modifying entry "uid=user1,ou=people,dc=example,dc=com"

The member attribute belongs on group entries, not on a person entry whose object classes do not permit it through inherited MUST or MAY rules. Check both inherited MUST and MAY attributes. An attribute does not have to appear in a MAY list if another assigned class requires it through MUST.

Choose the appropriate correction:

  • Remove the unsupported attribute from the modify
  • Add an existing auxiliary object class that legitimately allows it
  • Use a more appropriate entry type
  • Define a custom auxiliary object class for application-specific data in custom schema

Do not add an unrelated structural object class only to make one attribute acceptable. The auxiliary extensibleObject class permits additional user attributes, but it should not replace properly designed auxiliary schema for application data.

Multiple structural classes are valid when they form one inheritance chain, such as person, organizationalPerson, and inetOrgPerson:

text
person
└── organizationalPerson
    └── inetOrgPerson

Error 65 can occur when an entry combines unrelated structural classes, such as that person chain with an unrelated structural class such as organization.

Removing an object class while its attributes remain produces the same error family. On a posixAccount entry, deleting posixAccount without removing uidNumber returns:

output
ldap_modify: Object class violation (65)
	additional info: attribute "uidNumber" not allowed

Removing an auxiliary object class while leaving attributes that only that class permits normally produces error 65. Attempting to replace or change the entry's structural object class can instead produce error 69, objectClassModsProhibited. Adding or removing classes within the same valid structural inheritance chain is different from changing the entry to an unrelated structural type. RFC 4511 defines error 69 specifically for prohibited object-class modifications, including attempts to change an entry's structural object class.

When you remove an object class, remove attributes that are no longer allowed in the same logical change. When you add an object class, add its required attributes at the same time. Complete entry conversion and structural object class limitations are covered in schema validation and repair.


Check plug-ins, imports, and custom schema

Plug-in-generated attributes

The MemberOf plug-in can encounter error 65 when the target entry's object classes do not allow the memberOf attribute. When memberofAutoAddOC is configured, the plug-in first adds that configured object class and retries the update. Without a suitable auto-add class, the update is rejected. Verify both the target entry's object classes and the MemberOf plug-in configuration.

Similar failures can occur whenever a plug-in attempts to add or modify an attribute that the resulting entry schema does not permit. Check the specific plug-in log message and the target entry rather than assuming all plug-ins use MemberOf's auto-add behavior.

LDIF import failures

When error 65 occurs during export or import, inspect the rejected entry for missing required attributes, unsupported attributes, missing custom object classes, and incorrect object class combinations. Fix the LDIF or install legitimate custom schema instead of disabling schema checking as a routine workaround.

Custom schema problems

Before you add a value for a custom attribute, confirm that the attribute and auxiliary object class are loaded:

bash
dsconf ldap1 schema objectclasses query glcEmployee

Sample output when the class is not present:

output
None

Schema added or replaced through dsconf should be reloaded and then verified with a schema query. When you deploy or modify a schema file manually, use the same reload workflow:

bash
dsconf ldap1 schema reload --wait

Verify the object class:

bash
dsconf ldap1 schema objectclasses query glcEmployee

Review the errors log before testing entries:

bash
sudo tail -n 50 /var/log/dirsrv/slapd-ldap1/errors

Do not modify standard schema definitions to accommodate application data. Keep attribute and object class creation in custom schema.


Check schema consistency across replicas

Test the same ldapadd or ldapmodify directly against each server in the topology.

If the change succeeds on one replica but returns error 65 on another, compare custom object class definitions, custom attribute definitions, MUST and MAY lists, attribute syntax, single-value settings, loaded schema files, and nsSchemaCSN on each host. A supplier that defines glcEmployee while a consumer still returns None from dsconf ldap1 schema objectclasses query glcEmployee explains why the same LDIF succeeds on one server and fails on another.

Custom schema managed through cn=schema is recorded in 99user.ldif with a schema CSN. It is not pushed immediately as an ordinary replication operation. A later replicated content update triggers schema-CSN comparison, after which a compatible superset schema can propagate. Custom schema files outside 99user.ldif remain local and must be installed and reloaded on every server. Keep complete schema replication behaviour in custom schema and replication.


Verify the fix

Repeat the original ldapadd or ldapmodify command. A successful add prints:

output
adding new entry "uid=err65test,ou=people,dc=example,dc=com"

Confirm the stored entry:

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

The retest creates a new LDAP connection, so inspect the latest access-log entries rather than expecting an older err=65 line to change:

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

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

Retest the application, LDIF import, plug-in operation, or replicated update that originally failed. When the failure was intermittent across replicas, test every server directly.

Remove lab-only entries when you finish:

bash
ldapdelete -x -H ldap://ldap1.example.com:389 -D "cn=Directory Manager" -y /root/dm.pw "uid=err65test,ou=people,dc=example,dc=com"

Troubleshooting

Symptom Likely cause Check
Add fails with error 65 Required attribute missing Object class MUST attributes with --include-sup
Adding one attribute fails Attribute is not allowed Inherited MUST and MAY attributes and auxiliary classes
Removing an object class fails Unsupported attributes remain Final entry contents
Adding an object class fails Required attributes were not added Object class definition
Unrelated structural object classes cannot form one valid structural chain Structural object-class conflict Object class kinds and hierarchy
MemberOf update returns error 65 Entry does not permit memberOf Target entry object classes and memberofAutoAddOC
LDIF import fails Imported entries do not match local schema Rejected entry and custom schema
Works on one replica only Schema definitions differ Compare dsconf schema and nsSchemaCSN on each server
Error is 17 Attribute type is undefined Confirm the attribute exists in server schema
Error is 21 Attribute value has invalid syntax Attribute syntax and value format
Error is 69 Structural class is being changed Preserve the structural object class
Add succeeds but later modify fails Modification creates an invalid final entry Compare entry before and after the change

References


Summary

LDAP error 65 in 389 Directory Server means the resulting entry would violate object class rules. Reproduce the exact LDIF, read the additional info line, inspect the entry's object classes and attributes, and query dsconf ldap1 schema objectclasses query --include-sup for inherited MUST and MAY requirements. Fix missing required attributes, remove or reclassify disallowed attributes, coordinate object class additions and removals with attribute changes, and compare schema across replicas when the same operation behaves differently on different hosts.


Frequently Asked Questions

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

Error 65 means the resulting LDAP entry would not comply with its object class definitions. The additional info line often names a missing MUST attribute, a disallowed attribute, or an invalid object class combination. Schema validation applies to the complete entry after the requested change.

2. What is the difference between LDAP error 17 and error 65?

Error 17 means the request names an attribute type that the server does not recognize. Error 65 means the resulting entry violates object-class rules, including missing required attributes, disallowed attributes, invalid structural-class combinations, or an unknown object-class value. Confirm whether the diagnostic names an attribute type or an object class before choosing the fix.

3. Why does ldapadd fail with missing attribute sn?

The person object class requires sn. inetOrgPerson inherits that requirement through organizationalPerson and person. Add sn in the same LDIF as the object classes, or choose an entry type whose MUST attributes you can supply.

4. Can I disable schema checking to import invalid LDIF?

Technically yes, but it should not be used as a normal solution for an invalid import. Disabling schema checking can admit entries that violate required attributes, allowed attributes, and structural object-class rules. Fix the LDIF or install the legitimate custom schema instead. If schema checking is disabled temporarily for controlled recovery, re-enable it and validate or repair every imported entry.

5. Why does the same ldapmodify work on one replica but return error 65 on another?

Custom schema can differ temporarily between replicas. Schema managed through cn=schema is propagated when a later replicated content update triggers schema-CSN comparison, while manually installed schema files remain local. Query the object class and attribute definitions directly on every server and compare nsSchemaCSN before blaming the LDIF.
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 …