Stop chasing random schema errors
You’re trying to update an Active Directory schema attribute — maybe adding a new attribute or modifying an existing one — and you get hit with 0X000020BF. I know it’s annoying. Let’s cut straight to the fix.
The fix — it’s always the range values
The culprit here is almost always a swapped Range-Lower and Range-Upper. Someone — or some poorly written script — set Range-Lower to a number larger than Range-Upper. AD won’t let that slide. The error code translates to “Range-Lower less than Range-Upper”, meaning the lower bound must be less than the upper bound. That’s the whole story.
You fix it by editing the attribute definition in the Schema MMC snap-in or via ADSI Edit. Here's the step-by-step:
- Open Active Directory Schema snap-in (register it if needed with
regsvr32 schmmgmt.dll). - Navigate to Attributes and find the attribute that’s failing.
- Right-click → Properties → Attribute Syntax tab.
- Check the Range-Lower and Range-Upper values.
- If Range-Lower is larger than Range-Upper — swap them. If both are zero (integer range) or empty, set them properly. For example, a valid integer range: Range-Lower = 0, Range-Upper = 65535.
- Click OK and retry the schema update.
If the Schema snap-in is grayed out or you’re on a domain controller without Schema Admins rights, you’ll need to use ADSI Edit instead:
1. Open ADSI Edit.
2. Connect to: Configuration (default naming context).
3. Navigate to: CN=Schema,CN=Configuration,DC=yourdomain,DC=com
4. Find the attribute in CN=Schema (look for CN=attribute-name).
5. Right-click → Properties.
6. Edit the rangeLower and rangeUpper attributes.
7. Set rangeLower to a value strictly less than rangeUpper. Common fix: rangeLower = 0, rangeUpper = 1000000.
8. Click OK.
That’s it. The schema update will now pass.
Why this happens
Active Directory uses rangeLower and rangeUpper to define the valid length or value range for an attribute. If you’re defining a string attribute, rangeLower is the minimum length, rangeUpper is the maximum. For integer attributes, it’s the minimum and maximum allowed value. When you set rangeLower higher than rangeUpper, AD sees a logical contradiction. It’s like saying “this text must be between 10 and 5 characters long” — doesn’t make sense. AD enforces this validation at schema update time, giving you 0X000020BF.
The most common real-world trigger? A junior admin or automated provisioning script reverses the two values when generating the LDIF file. I’ve seen it happen with Microsoft Identity Manager (MIM) and third-party sync tools that generate schema extensions incorrectly. Also happens if someone manually edits the schema with ADSI Edit and fat-fingers the numbers.
Less common variations of the same issue
Variation 1: Both values are zero, but schema still fails
If rangeLower and rangeUpper are both 0 for an integer attribute, AD might reject it if the attribute syntax expects a non-zero range. For example, attributes of syntax “Integer” (cn=Integer) typically need both values set. In that case, set them to something like rangeLower=0, rangeUpper=1000000. Don’t leave them empty.
Variation 2: The error appears during schema-wide import (LDIFDE)
You’re running ldifde -i -f schema.ldf and it bombs out. Same root cause — one or more attribute definitions in the LDF file have reversed range values. Open the LDF in Notepad, search for “rangeLower” and “rangeUpper”, and correct them. Then re-run.
Variation 3: Schema update fails on a class definition, not an attribute
Rare, but I’ve seen it. The error might reference a class (objectClass) instead of an attribute. The fix is the same — check the classSchema object’s rangeLower and rangeUpper properties. Usually these aren’t set, but if they are, ensure rangeLower < rangeUpper.
Variation 4: The attribute is system-critical and you don’t have permissions
Some built-in attributes (like sAMAccountName) are read-only. You’ll get a different error if you try to modify them — usually access denied. But if you see 0X000020BF on a system attribute, you’re probably misreading the error. Double-check you’re editing the right object.
Prevention — save yourself the headache
- Always validate range values before applying schema updates. Write a quick PowerShell check:
Get-ADObject -SearchBase "CN=Schema,CN=Configuration,DC=yourdomain,DC=com" -Filter {objectClass -eq "attributeSchema"} -Properties rangeLower, rangeUpper |
Where-Object { $_.rangeLower -gt $_.rangeUpper -and $_.rangeUpper -ne $null }
- If you’re using LDIFDE for bulk changes, add a pre-checks step. Write a script to parse the LDF file and flag any attribute where rangeLower >= rangeUpper before importing.
- Never let a script generate range values without human review. The most common cause is an automated tool that doesn’t enforce the constraint. For example, a script that sets rangeLower to the string length of a sample value and rangeUpper to a hardcoded max — easy to swap accidentally.
- Test schema updates in a lab first. If you don’t have a lab, at least run the update on a single DC that you can restore from backup.
- Document the intended range values for every custom attribute. If someone leaves the company, the next admin shouldn’t have to guess.
Bottom line: this error is a simple validation check. Fix the range values and move on. Don’t waste time reinstalling the schema master or rebuilding the domain — that never helps.