Quick Answer
Use a concrete (structural) class instead of the abstract one—for example, instead of user use organizationalPerson or a custom subclass. Or, if you absolutely need the abstract class, change its objectClassCategory to 1 in the schema (not recommended in production).
Why This Happens
Active Directory uses a class hierarchy. Some classes are defined as abstract—they exist only to organize attributes and can't have actual objects created from them. When you try to create an object of such a class, you get ERROR_DS_CLASS_MUST_BE_CONCRETE (0X000020A7). This usually shows up during a scripted LDAP add operation or in a tool that lets you pick a class manually. I've seen it most often when someone tries to create a contact object using the person class (which is abstract).
The error message is blunt: "The class of the object must be structural; you cannot instantiate an abstract class." That's exactly what it means—AD won't let you create an instance of a class that's marked abstract in the schema.
Fix Steps
- Identify the class you're actually using. Look at your LDAP add command or script. Find the
objectClassattribute. Common abstract classes in AD:top,person,device,serviceConnectionPoint(yes, that one is abstract), andmailRecipient. - Pick a concrete subclass. For users, use
user(which is structural) ororganizationalPersonif you're creating a contact. For computers, usecomputer. For groups,group. If you're writing a script, changeobjectClass: persontoobjectClass: user. - Test your change. Run the add operation again. If it succeeds, you're done. If you get a different error, check that the subclass has all required attributes (like
cnandsAMAccountName).
Example: Fixing a PowerShell script
Here's a snippet that triggers the error:
New-ADObject -Name "Test" -Type person -Path "OU=Users,DC=contoso,DC=com"Change -Type person to -Type user:
New-ADObject -Name "Test" -Type user -Path "OU=Users,DC=contoso,DC=com"That should work.
If the Main Fix Doesn't Work
Sometimes you're stuck with an abstract class because a third-party app expects it. In that case, you have two options:
- Modify the schema (only if you control the schema and know what you're doing). Use ADSI Edit to change
objectClassCategoryfrom 2 (abstract) to 1 (structural) on the class. Back up the schema first. This is risky—it can break other things. - Use a different tool that maps the class correctly. For example, instead of raw LDAP, use
dsaddor the ADUC console, which always use concrete classes under the hood.
Prevention Tip
Before writing any script that creates AD objects, check the class's objectClassCategory in the schema. You can query it with PowerShell:
Get-ADObject -SearchBase (Get-ADRootDSE).SchemaNamingContext -Filter {Name -eq 'person'} -Properties objectClassCategoryIf it returns 2, don't use it. Also, always test your script in a lab environment first. I've seen this error trip up junior admins more than once—it's easy to assume any class works.