You may experience problems performing mailbox move operations if the number of characters on a given Exchange attribute is greater than the default values defined by /SchemaPrep. Most commonly this issue occurs because of an administrative and unsupported edit of the Schema to allow for more characters to be present on a given user attribute. Afterwards when the Mailbox-Move is attempted new Move-Mailbox prevalidation logic runs and ultimately fails the move if the user has a larger number of characters present on the object than that which was defined by /SchemaPrep for the attribute. This error will only manifest itself when the source or target of a mailbox move is an Exchange 2007 mail store. When the Mailbox Move fails the following error will be displayed in the Exchange Management Console:
<Attribute Name> is too long: maximum length is "x" and the actual length is "y"
The inspiration for this post came from a real issue I troubleshoot within Exchange Escalations Support. Throughout this post, I will be referencing and providing examples based upon Exchange Custom Attribute 2 (e.g. extensionAttribute2). However a failure could occur on any attribute that exceeds the upper limit set by /SchemaPrep which I will detail later in this post.
Primary Issue and Symptoms:
As previously noted, the primary symptom at play was that an Exchange Administrator was experiencing intermittent failures when utilizing the Exchange Management Console (EMC) or Exchange Management Shell (EMS) to perform Mailbox Moves. When the move failed an error similar to what is documented below would occur:
Error: Custom Attribute2 is too long: maximum length is 1024 and the actual length is "1358"
Additionally when running Get-Mailbox against the impacted user mailbox the administrator would receive an error about the object being corrupt:
Warning: Object domain.com/Users/TestUser has been corrupted and it is in an inconsistent state.
The following validation errors have occurred:
Warning: CustomAttribute2 is too long: maximum length is 1024 and the actual length is 1358.
The error being referenced would suggest that the mailbox is failing to move due to a large number of characters being present on the aforementioned attribute (msExchAttribute2). The most logical place to begin troubleshooting would be to first determine whether or not a large number of characters are in fact present on the user object in the Active Directory. A number of techniques can be used to determine this:
- ADSI Edit
- Traditional Scripting
- Exchange Management Console:
- In the Console Tree of the Exchange Management Console select the Mailbox node under Recipient Configuration.
- Depending on how large your organization is you may want to increase the number of recipients to display in the Actions pane.
- Select View and then Add/Remove columns.
- Select CustomAttribute2 select Add, then move it into the Displayed Columns list (you may want to move it to the second column in the list under Display Name), then click OK.
- The Mailboxes Node will load albeit with warnings. If you open the Warnings dialog, a list of all users in this state will be presented:
- Windows PowerShell:
Note: If you save this script as a .ps1 file, once executed it will write to the console every user who has over 1024 characters on Extension Attribute 2. If you are receiving the error for a different attribute you can change the attribute as applicable (shell syntax courtesy of my friend and colleague Mike Hendrickson):
foreach ($mailbox in Get-Mailbox)
if ($mailbox.CustomAttribute2.Length -gt "1024")
Write-Host "Name: $($mailbox.Name)"
Write-Host "Length: $($mailbox.CustomAttribute2.Length)"
Initially in my case I used LDP to "dump" the impacted user object and successfully determined that a large amount of characters were in fact present on extensionAttribute2. I then wanted to verify that the Exchange tools were calculating the value correctly. To do so, I used a very simple technique:
- Within LDP, copy the complete contents of the attribute to the clip-board.
- Open Notepad, disable word-wrap and add the Status Bar.
- Copy the complete value into Notepad.
- Calculate the total amount of characters.
To calculate the characters:
- With Word-Wrap disabled a single line can only contain 1024 characters.
- With the Status-Bar enabled you can get an exact character count for the last line by simply placing the cursor at the end of the last character (will be displayed in the status window).
- To calculate, you simply multiple the number of complete lines by 1024 and add the value of characters from the last line.
So in my case, I had one complete line and an incomplete line that had 334 characters present.
1024 + 334 = 1358
This one test allowed me to deduce that yes this one object failing to move did have a lot of characters present on the documented attribute in the Active Directory, and that Exchange was in fact calculating the value accurately.
The next logical troubleshooting step would be to determine what the upper limits for this attribute are in the Active Directory Schema.
Verifying the Limits of Extension Attribute 2 in the Windows Schema:
In the Windows schema there is an object of type attributeSchemaClass for Exchange Extension Attribute 2. The actual display name of this object is: ms-Exch-Extension-Attribute-2.
This object (as well as all other Exchange related objects and classes) are created when /PrepareSchema (or in previous versions /forestprep) is ran. The minimum and maximum character values for objects are always defined by two specific attributes:
rangeLower: (being the minimum value)
rangeUpper: (being the maximum value)
I proceeded to take an LDP dump of the ms-Exch-Extension-Attribute-2 object out of the customer's schema (Note: the distinguishedName of this object would be something similar to CN=ms-Exch-Extension-Attribute-2,CN=Schema,CN=Configuration,DC=<DOMAIN>,DC=com').
What immediately became obvious is that the rangeUpper value for this object apparently supported 10240 characters:
Expanding base 'CN=ms-Exch-Extension-Attribute-2,CN=Schema,CN=Configuration,DC=<DOMAIN>,DC=com'...
Result <0>: (null)
Getting 1 entries:
>> Dn: CN=ms-Exch-Extension-Attribute-2,CN=Schema,CN=Configuration,DC=<DOMAIN<,DC=com
2> objectClass: top; attributeSchema;
1> cn: ms-Exch-Extension-Attribute-2;
1> distinguishedName: CN=ms-Exch-Extension-Attribute-2,CN=Schema,CN=Configuration,DC=<DOMAIN>,DC=com;
1> instanceType: 0x4 = ( IT_WRITE );
1> whenCreated: 04/03/2002 15:15:43 Pacific Standard Time Pacific Daylight Time;
1> whenChanged: 04/12/2009 17:20:51 Pacific Standard Time Pacific Daylight Time;
1> uSNCreated: 6732;
1> attributeID: 1.2.840.1135126.96.36.1994;
1> attributeSyntax: 188.8.131.52;
1> isSingleValued: TRUE;
1> rangeLower: 1;
1> rangeUpper: 10240;
1> mAPIID: 32814;
1> uSNChanged: 46036019;
1> showInAdvancedViewOnly: TRUE;
1> adminDisplayName: ms-Exch-Extension-Attribute-2;
1> adminDescription: ms-Exch-Extension-Attribute-2;
1> oMSyntax: 64;
1> searchFlags: 17;
1> lDAPDisplayName: extensionAttribute2;
1> name: ms-Exch-Extension-Attribute-2;
1> objectGUID: bc303dd3-f496-4c60-a5fa-8647a42dd063;
1> schemaIDGUID: bf967969-0de6-11d0-a285-00aa003049e2;
1> attributeSecurityGUID: 1f298a89-de98-47b8-b5cd-572ad53d267e;
1> isMemberOfPartialAttributeSet: TRUE;
1> objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=<DOMAIN>,DC=com;
So we can see here that the rangeLower value is set to 1 (which would be expected) and the rangeUpper value is set to 10240 (which would mean that the attribute itself can allow for 10240 individual characters). This large value explains why the failed object could have 1358 characters present on the AD object, but doesn't explain why the Mailbox Move operation would expect the value to be less than 1024.
At first glance this looks like a really...really big bug. Why would we allow you to store 10240 characters on an attribute but fail a mailbox-move because we expect the value to be less than 1024 characters?
But, under closer examination what struck me as curious was the relatively recent update to the object. In the LDP dump above you will notice that the whenChanged value for this object is: 04/12/2009 17:20:51 (early on in the call the customer had told me that they began deploying CAS servers in the environment nearly a year before hand). The whenChanged value in and of itself could be perfectly explainable (e.g. perhaps they decided to roll out SP1 which requires an upgrade of the Schema). On the other hand, perhaps a manual edit of the schema was performed to allow for this many characters.
At this point, I wanted to continue troubleshooting by performing two valid action items:
- Compare the whenChanged value on another Exchange attribute (theoretically the whenChanged value "should be" nearly the same, as all Exchange objects should have been modified at roughly the same time (e.g. when /SchemaPrep was run)).
- Verify the default value for ms-Exch-Extension-Attribute-2 as defined in the LDF files for Exchange 2007 /SchemaPrep.
Result of Troubleshooting Steps:
I took an LDP dump of ms-Exch-Extension-Attribute-1 and determined that its "whenChanged" value was much older than that contained on ms-Exch-Extension-Attribute-2. Immediately I began to suspect that an unsupported schema edit had been performed. Next I decided to review the LDF files.
To be clear, when /PrepareSchema is run a series of LDF files are imported to define classes and valid attributes for mail enabled objects. Amongst other things it will set the valid ranges on some of the attributes being added or modified within the schema. In Exchange 2007 there are 100 of these files stored on the installation media and are sequentially named schema0.ldf - schema99.ldf. These files can be opened and reviewed easily in notepad.
In my case, I got lucky because ms-Exch-Extension-Attribute-2 was defined in the first LDF file (schema0.ldf).
Note: If you are troubleshooting a different attribute and are having difficulty locating where this attribute is defined in the Schema LDF files, you may want to compile a master file (e.g. one comprised of all 100 LDF files) then simply search the file for the object you are looking for. This could save valuable time and insulate you from human error as you don't have to have all 100 files open (worst case scenario I suppose). For the record, it's supported to "look" in this fashion but not supported to update the schema in this way).
In my case, I found ms-Exch-Extension-Attribute-2 easily enough in schema0.ldf:
Notice how rangeUpper = 1024.
So at this point it is pretty safe to assume that a Schema Administrator (the only type of user who can make such a change) went in and manually modified the rangeUpper value on this object. In this case it looks like a "0" was simply appended to 1024.
At this point, I was informed that there is a certain 3rd party tool out there that stores application specific user information on extensionAttribute2 and that the edit was necessary to allow the tool to work properly.
Are Schema Edits Supported?
Very simply, edits to the default Exchange schema have and never will be supported. The reason is that it is entirely possible that functionality could be added or removed that is dependent upon the values we expect to be present (as in this case). If you choose to go down this path your risks include but aren't necessarily limited to:
- Your Active Directory and Exchange implementation not working as expected.
- Being unsupported.
More Troubleshooting (a work-around):
The information contained within extensionAttribute2 on our failed users was simply string information. As we had a valid LDP dump for a user, I had the customer temporarily remove the entire string (although simply removing 335 characters would have allowed the move to complete) via ADSI Edit. Once done, we retried the move which completed successfully. After the move, we added the value back via ADSI Edit and verified that the 3rd party tool continued to function properly.
Without going into a tremendous amount of detail here (there are many...many articles on the subject), Exchange 2007 now runs a series of pre-validation checks prior to actually performing a mailbox move. This was done in effort to try and reduce situations where partially provisioned accounts/mailboxes would exist as the result of a partially completed move (e.g. a failure where items may have been moved but some problem occurred in updating the AD, et cetera). Any administrator who has been tasked with this type of cleanup knows how tedious it can be. Thus, these checks were added as a precautionary measure to help alleviate this type of situation.
What's important to remember with respect to the scope of this sort of issue is to first know that these checks exist. The "technical stuff" is that within Move-Mailbox code there is a hard-coded validation lookup table. One of the checks it performs prior to allowing a move is to verify whether a user has more than 1024 characters on extensionAttribute2 (e.g. the value Exchange setup defined in the schema via /SchemaPrep). If the user does have something greater than 1024 characters, the pre-validation check fails the move procedure. This check is hard coded. That is to say, there is no LDAP call into the Active Directory to verify what the current allowable upper bounds are for the rangeUpper attribute in the Schema partition. So, although the edit was technically sound in theory, the mailbox move will continue to fail until it is less than 1024 characters.
Even though a "valid" work around was provided to the customer (yes... tedious, but administratively could be made much easier via shell exports and/or scripting), the best overall solution would have been for the vendor to create their own unique attributes that extended the user object class, defined the range and then wrote their values to an "intentional" attribute. Because these attributes would be unique to their application, they would never be checked in some sort of Exchange validation code.
Resources for Accomplishing This:
1. Extend the Schema:
2. Extend the User Class in the AD Schema:
3. Contact the IANA to acquire valid OIDs:
Prior to signing off, I have witnessed a lot of confusion concerning the acceptable values or "ranges" for Exchange Extension attributes. I wanted to provide you with a definitive list for all the Exchange Extension Attributes as well as their relevant values as defined in the SCHEMA*.ldf files. The short story (or as I like to say..."the Reader's Digest version") is that 1-10 can contain up to 1024 characters, whereas 11-15 support up to 2048 characters.
Schema Object Definitions and ranges as defined in the Exchange 2007 SCHEMA*.LDF files:
ms-Exch-Extension-Attribute-1 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-2 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-3 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-4 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-5 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-6 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-7 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-8 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-9 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-10 -- rangeUpper: 1024
ms-Exch-Extension-Attribute-11 -- rangeUpper: 2048
ms-Exch-Extension-Attribute-12 -- rangeUpper: 2048
ms-Exch-Extension-Attribute-13 -- rangeUpper: 2048
ms-Exch-Extension-Attribute-14 -- rangeUpper: 2048
ms-Exch-Extension-Attribute-15 -- rangeUpper: 2048
I hope you found this article interesting/useful.
If you did, please leave some feedback.