Converting a SharePoint 2010 web application from Classic mode authentication to Claims Mode authentication is fairly well documented.
After enabling claims mode, it is necessary to use the MigrateUsers() method to reformat the permissions entries in the Content Databases to reflect the Claims mode format.
I have done several such conversions before without error, but this past weekend I tried another one for a client and ran in to an unusual error.
The Web Application contained 3 content databases, and 4 site collections.
The MigrateUsers call appeared to run successfully, and it reported no errors to the Powershell session.
As we were testing access to the site collections, however, it became clear that one of the site collections had not been converted.
In reviewing the ULS logs, the following entry revealed that an error had occurred during the run of the MigrateUsers method:
Migration for site <null> failed: Object reference not set to an instance of an object. at at Microsoft.SharePoint.Administration.SPWebApplication.LogMigrationError(String name, String objectType, Exception e) at Microsoft.SharePoint.Administration.SPWebApplication.MigrateDatabaseHelper(SPContentDatabase database, SPCommonMigrateUserParameters commonParams, Dictionary`2 processedOldLogins) at Microsoft.SharePoint.Administration.SPWebApplication.MigrateUsers(IMigrateUserCallback callback) at MigrateUsers(Object , Object ) at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object arguments, MethodInformation methodInformation, Object originalArguments) at System.Management.Automation.DotNetAdapter.MethodInvokeDotNet(String methodName, Object target, MethodInformation methodInformation, Object arguments) at System.Management.Automation.Adapter.BaseMethodInvoke(PSMethod method, Object arguments) at System.Management.Automation.ParserOps.CallMethod(Token token, Object target, String methodName, Object paramArray, Boolean callStatic, Object valueToSet) at System.Management.Automation.MethodCallNode.InvokeMethod(Object target, Object arguments, Object value) at System.Management.Automation.MethodCallNode.Execute(Array input, Pipe outputPipe, ExecutionContext context) at System.Management.Automation.ParseTreeNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context) at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context) at System.Management.Automation.StatementListNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context) at System.Management.Automation.ParseTreeNode.Execute(Array input, Pipe outputPipe, ExecutionContext context) at System.Management.Automation.ScriptCommandProcessor.ExecuteWithCatch(ParseTreeNode ptn, Array inputToProcess) at System.Management.Automation.ScriptCommandProcessor.RunClause(ParseTreeNode clause, Object dollarUnderbar, Object inputToProcess) at System.Management.Automation.CommandProcessorBase.DoComplete() at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate) at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper() at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc() at System.Management.Automation.Runspaces.PipelineThread.WorkerProc() at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
I’ll trim out the awful details of sitting on the phone with Microsoft technical support, and jump right to the fix.
It turned out that when this SharePoint farm was upgraded from 2007 to 2010, there was a residual site collection in one of the content database. Further, it so happened that this site collection had the same name and url as a sub site in another site collection.
It appeared that as the MigrateUsers method was iterating through the site collections, it would follow the url to open the site collection and retrieve the users in order to convert them. In this case, however, the url led not to a site collection, but a sub site, and thus the ‘Object reference not set to an instance of an object.’ error occurred.
After confirming that the residual site collection was unused and contained no content, I (nervously) deleted it in Central Administration.
I then re-ran the MigrateUsers() method, and it successfully converted the users for all site collections, and users were able to authenticate properly to the sites.
I recognize this is an unusual situation due to the particular data in this installation. But having found very little information about any such case, I wanted to share my experience.