Active Directory can't replace a hidden record — 0X000020E8 fix
Happens when LDAP tries to replace an object that's marked as hidden in Active Directory. The fix: un-hide the record or delete and recreate it.
When this error hits
You're running a script or a tool that uses LDAP to modify an object in Active Directory — maybe updating a user attribute, changing a group membership, or replacing a service connection point. The operation fails with ERROR_DS_CANT_REPLACE_HIDDEN_REC (0X000020E8). This happens most often on Windows Server 2016 or 2019 domain controllers when a third-party app (like Exchange, Skype for Business, or a custom LOB app) has marked the object as hidden.
The exact trigger: your code calls ldap_modify or ldap_modify_ext with the LDAP_REPLACE operation on an attribute, but the object's isDeleted flag is set to TRUE or the object resides in a hidden container (like the Deleted Objects container). You can't replace attributes on tombstoned or hidden records — the directory won't let you.
Root cause
What's actually happening here is that Active Directory protects hidden records from accidental modification. The isDeleted attribute is a system-only flag. When an object is tombstoned (soft-deleted), AD sets isDeleted=TRUE and moves it to the Deleted Objects container. That container itself has the showInAdvancedViewOnly attribute set to TRUE, which hides it from most LDAP searches unless you explicitly specify LDAP_SCOPE_BASE or use a control like LDAP_SERVER_SHOW_DELETED_OID.
The reason LDAP_REPLACE fails is that AD enforces a rule: you cannot replace any attribute on an object that's marked as deleted, except for a few system-managed ones like lastKnownParent. The 0X000020E8 code is the directory's way of saying "this record is hidden, you can't swap out its values."
Common scenarios that cause this:
- A user or group was deleted but the deletion didn't fully replicate, leaving a lingering tombstone.
- A sync tool (like Azure AD Connect) created a placeholder object that later got tombstoned.
- Someone accidentally ran a cleanup script that soft-deleted the wrong object.
- The object itself was never a real record — it's a system-generated phantom (like a cross-reference object in the Partitions container).
Fix: un-hide or recreate
You have three options. I'd recommend option 1 first — it's the least destructive.
Option 1: Use ADSI Edit to un-hide the object
- Open ADSI Edit (add it via Server Manager → Tools if not already there).
- Right-click ADSI Edit → Connect to. Choose Default naming context or the specific partition where the object lives.
- In the tree, navigate to the object that's failing. If you can't see it, go to View → check Show deleted objects and Show all objects.
- Right-click the object → Properties.
- Find the
isDeletedattribute. If it'sTRUE, you can't change it directly — AD doesn't allow writing to system attributes. - Instead, delete the object permanently: right-click → Delete. Then recreate it manually or via your script.
Option 2: Delete and recreate from scratch
If the object is tombstoned, you can't resurrect it cleanly. Run this PowerShell snippet to list and then remove it:
Get-ADObject -Filter {Name -eq "YourObjectName"} -IncludeDeletedObjects | Remove-ADObject -confirm:$false
Then create a fresh object:
New-ADObject -Name "YourObjectName" -Type "user" -Path "OU=Users,DC=domain,DC=com"
Replace Type and Path with your actual values. This is the nuclear option — it works every time.
Option 3: Use LDAP controls to skip the check (advanced)
If you're writing code and can't delete the object, you can try the LDAP_SERVER_SHOW_DELETED_OID control. But this only lets you read or undelete an object — it still won't let you replace attributes on a tombstone. The only thing you can do is restore it using ldap_modify with isDeleted=FALSE. Once restored, you can then replace attributes normally.
# PowerShell example to undelete
$obj = Get-ADObject -Filter {Name -eq "YourObjectName"} -IncludeDeletedObjects
$obj | Restore-ADObject
After restoration, your original replace operation should work.
If it still fails
Check these three things:
- Replication health: Run
repadmin /showreplon all domain controllers. If the tombstone hasn't replicated everywhere, you'll see inconsistent behavior. Wait for replication or force it withrepadmin /syncall. - Object GUID mismatch: Sometimes your script references the object by a stale GUID. Use
Get-ADObject -IncludeDeletedObjects -Filter {ObjectGUID -eq "to verify the object still exists with that GUID."} - System-only attributes: If the object is a system object (like
CN=NTDS Settings), you can't modify it at all. Don't try — you'll just get more errors.
The bottom line: 0X000020E8 means the record is hidden. Stop trying to replace it. Either delete and recreate, or restore it first, then modify.
Was this solution helpful?