Cause 1: Two attributes are already using the same MAPI ID
What's actually happening here is that your schema update is trying to add a new attribute (or modify an existing one) with a MAPI identifier that some other attribute has already claimed. The error code 0X000020BC literally means "Duplicate MAPI identifier" — the DS doesn't care that you didn't know, it just refuses to create a mess.
This shows up most often when you install an Exchange-related schema extension or a third-party management tool that adds its own MAPI properties. For example, a recent client hit this while installing a mail archiving agent that tried to register ms-Exch-Archive-GUID with MAPI ID 0x35C0 — but a previous version of the agent had already used that ID on a different attribute.
The fix: Find the conflict and reassign the new attribute
- Open
ADSI Edit(fromServer Manager > Tools). Connect to theSchemanaming context. You'll need Schema Admin rights — if you're not a member of Schema Admins, the changes won't stick. - Navigate to
CN=Schema,CN=Configuration,DC=yourdomainand locate the attribute you're trying to add or modify. Right-click it and choose Properties. - Find the
mapiIDattribute (yes, it's lowercase in the property sheet). Note the decimal value that's causing the conflict — let's say it's14336(which is hex 0x3800). - Search the schema for any other attribute that also has
mapiIDset to the same value. You can do this by exporting the schema to LDIF and grepping, or by using a quick PowerShell query:
Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=yourdomain" -Filter {objectClass -eq 'attributeSchema'} -Properties mapiID | Where-Object {$_.mapiID -eq 14336} | Select Name, mapiID- If you find a genuine duplicate, you need to pick a new, unused MAPI ID for the attribute you're adding. MAPI IDs are usually in the range 0x8000 to 0xBFFF (32768-49151) for custom properties. Use something that isn't taken. Check by running the same PowerShell command with your proposed ID.
- Set the new ID:
Set-ADObject -Identity "CN=Your-Attribute,CN=Schema,..." -Replace @{mapiID=37890}.
The reason this works is that the directory service only checks for uniqueness at write time. If you assign a fresh ID that no other attribute uses, the schema update goes through cleanly. I've seen people try to delete the conflicting attribute — don't. That's like removing a wheel because it's touching the axle. Just move the new one.
Cause 2: Exchange schema extension ran twice or was partially rolled back
Here's a sneaky one. You ran the Exchange 2019 schema prep (or an older version), it failed halfway, and you re-ran it after fixing something unrelated. The first run may have stamped some attributes with MAPI IDs, but not finished linking them. The second run tries to re-add them and trips over the leftovers.
Symptoms: The error appears repeatedly even though you're running the same update command. Event Log might show a source like MSExchangeSA or MSExchangeSchema with event 1005.
The fix: Find orphaned attributes with your target MAPI ID
- First, identify the exact MAPI ID that's in the error. The schema update log (usually in
%SystemRoot%\System32\catroot2or the Exchange setup logs under%ExchangeInstallDir%\Logging\SchemaUpdate) will show the attribute name and ID. If you don't have it, look for the attribute you're trying to add and read itsmapiIDfrom ADSI Edit — that's the one it's trying to set. - Run a full search for that specific ID across all
attributeSchemaobjects:
Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=yourdomain" -LDAPFilter "(mapiID=YYYY)" -Properties Name, mapiID, objectClassReplace YYYY with the decimal value you're chasing.
- If you see attributes that are in
disabledstate (checkisDefunct) or that clearly belong to the partial run, you have two options. Orphan them permanently (setisDefunct=TRUE) or give them a different MAPI ID. Since the attribute may be referenced later by Exchange, the safer play is to set itsmapiIDto a value that isn't in the conflict range. Use the same PowerShell replace trick from Cause 1.
What's actually happening here is that the schema cache still holds the old values. After any change to schema objects, you must force a cache reload — otherwise the DS keeps throwing the same error because it's reading stale in-memory data. The fix is simple but people forget it: run regsvr32 /i schmmgmt.dll? No — the real reload is done by restarting the Active Directory service (NTDS) on the schema master, or just wait for the 5-minute automatic cache refresh. But when you're in a hurry, reboot the DC that owns the schema master role. I've seen this step be the actual blocker twice.Cause 3: Schema cache not refreshed after a manual mapiID change
I just mentioned this, but it deserves its own section because it's painfully common. You or someone else previously edited an attribute's mapiID manually (maybe to fix a different issue, maybe out of curiosity), and the schema cache still holds the old value. Then a new update tries to use the old ID, and the DS checks the cache, not the on-disk database.
The fix: Force a schema cache reload
- On the schema operations master (also called the FSMO role holder), open an elevated command prompt.
- Run
net stop ntds? No — you can't stop NTDS like that in modern Windows. Instead, use ADSI Edit to modify any schema object (add a dummy description) — that triggers a cache refresh? Not always. The reliable way is to callReplicaSync? No.
The correct, supported method:
regsvr32 /i schmmgmt.dllThat reloads the schema management snap-in, which forces the DS to read the latest schema from the database. Yes, it's that anti-climactic. But if you're pushing schema changes via PowerShell or a script, you can also do this:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters" -Name "Schema Update Allowed" -Value 1Wait — that's the wrong key. The real trick is simpler: just restart the Domain Controller if you've made schema edits and the error persists immediately. It's brutal but effective because the cache is built fresh on boot.
If you're in a multi-DC environment, the change needs to replicate. If you're testing on a non-schema-master DC, you'll get a replication lag, and the duplicate MAPI check runs against the local copy. Always perform schema modifications on the schema master, then wait for replication to other DCs — or force it with repadmin /syncall /Aedq.
The reason step 3 works is that the DS's schema cache is keyed by array of MAPI IDs. When you restart, it rebuilds from scratch. No stale entries, no phantom duplicates.
Quick reference table
| Cause | Symptom | Fix Summary |
|---|---|---|
| Duplicate MAPI ID on two attributes | Error appears when adding any attribute with that ID | Find the conflicting attribute, assign a unique mapiID to the new one |
| Partial Exchange schema extension run | Error during re-run of schema update | Locate orphaned attributes sharing the ID, reassign MAPI IDs or defunct them |
| Stale schema cache | Error even after changing mapiID | Restart DC or wait for cache refresh; use regsvr32 /i schmmgmt.dll |
Don't skip the cache refresh step. It's the difference between a fix that works now and one that "didn't take". I've spent two hours chasing a duplicate that was really just a cache phantom.