Content deployment in SharePoint 2010 works fantastically well. Once it is working. Getting to the ‘working’ stage however is a path that can cause a lot of pain, not the least of which is getting a generic error!
My configuration for our SharePoint publishing farm is as follows:
- SharePoint central admin site (PUB01)
- 2 x SharePoint web front-ends serving content (WFE01 and WFE02)
- Radware load balance (LOAD01)
I’m mentioning these items because they impacted how my content deployment was not working, and also the resolution required.
What You Absolutely Need To Have
There is ample documentation on setting up Content Deployment, but from a high level you must have the following in place:
- Your source Central Admin website must be able to access the destination Central Admin website, including setting the destination CA to accept content deployment. This includes the IP address and port of course!
- The account you use to deploy content on the destination server must have the appropriate permissions
- Your source and destination farms must be the same SharePoint version (right down to the Cumulate Update if applicable!)
- The destination CA must have enough room to store the content in a temporary location (check hard drive space on the destination server that hosts the Central Admin site)
- The destination CA must have the Microsoft SharePoint Foundation Web Application service “Started” on the server (destination CA uses this to check IIS configuration – more on this later)
Content Deployment Process
Content deployment goes through several high-level stages when it deploys content:
- The Source CA packages up the content into one or more CAB files
- The Source CA pushes the CAB files to the Destination CA, which stores them in a temporary location
- The Destination CA validates the IIS site and destination site collection
- The Destination CA unpacks the cab files and individually pushes the content into the destination site collection
The import log file shows the results of the attempted import and will display any warnings or errors that occurred.
System.NullReferenceException: Object reference not set to an instance of an object
In my environment, this error occurs very quickly after the data has been transferred to the destination farm. I dialed up the ULS diagnostic monitoring by editing the Monitoring, “Configure diagnostic logging”, “Category – Web Content Management/Content Deployment” setting to Verbose. Your ULS log file will then show much more detail about the process, including whether the CAB content files are being copied up properly from the source to the destination CA. Look for entries such as:
Upload file 'C:\SPDeploy\1c8b92e5-975c-4d30-b38e-04c25975e2bb\ExportedFiles9.cab' succeeded
The “System.NullReferenceException” error occurs very soon after the final CAB file has been deployed.
The thing that tripped me up was the load-balanced url I had set up in the Radware load-balancer and DNS settings. My destination URL DNS entry was pointing to the load-balancer virtual IP address, which then load-balanced requests to my two web front-end servers. My suspicion is that the destination Central Admin content deployment process checks IIS to see if it is configured correctly, and because it is traveling via a virtual IP address it doesn’t resolve to a local IIS metabase entry. In the ULS logs I saw entries such as:
Saving CachingSettings for SiteUrl 'http://your.sharepoint.url/'
immediately followed by the dreaded:
Failed import operation for Content Deployment job 'Remote import job for job with sourceID = 409e7be7-7694-496d-8469-eb472e5070f6'. Exception was: 'System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.SharePoint.SPSite.PreinitializeServer(SPRequest request)
at Microsoft.SharePoint.SPWeb.InitializeSPRequest()
at Microsoft.SharePoint.SPWeb.get_AllProperties()
at Microsoft.SharePoint.Publishing.SiteCacheSettings..ctor(SPSite site)
at Microsoft.SharePoint.Publishing.SiteCacheSettingsWriter..ctor(SPSite site)
at Microsoft.SharePoint.Publishing.SiteCacheSettingsWriter.SaveCacheSettingsBeforeImport(String importSiteUrl)
at Microsoft.SharePoint.Publishing.Administration.ContentDeploymentJob.DoImport()'
I checked the “PreInitializeServer” code using ILSpy (an improved, and more importantly free, replacement for Reflector), which wasn’t doing anything particularly complex but does use the SPRequest object. My thinking at this point was that the CA was unable to connect to IIS – it possibly does an IIS metabase lookup to get configuration settings, and because it was being bounced to the load-balancer and then down to the web front-ends, this step was failing. This occurs immediately after the cab files have been uploaded to the destination server.
The fix I put in was to edit the “hosts.” file (C:\Windows\System32\Drivers\etc\hosts.) and add an entry for the CA destination server IP address against the URL I was publishing to. This forces the destination CA to use the local server instead of trying to go via the load-balancer. This won’t affect the content being served, the web front-ends are configured via the load-balancer, and the destination CA doesn’t actually participate in this process. If your destination CA is also a web front-end, this would also still work as the URL resolves properly anyway.
After I set up my hosts file and re-ran the content deployment, it all worked perfectly! At least, on this occasion 🙂
A second “fix” I have had to use is to create another host-header site collection on my destination CA. I didn’t need to use this new site collection – I just created a blank one (see powershell script below). I’m not sure what happens in the background, but when I next tried my content deployment, it immediately changed from FAILED to SUCCESS. It’s possible that the act of creating another site collection resets Something(tm) so that content deployment can connect correctly.
Additional Content Deployment Troubleshooting Tips
While trying to diagnose the problem I also came up against the following issues (in no particular order):
- When creating a destination site collection, do not add a template to the site. In essence, you are creating an empty site collection, not a site collection with the blank or blank internet template. This breaks content deployment. I use the following Powershell script to auto-create a host-header (multi-tenancy) site collection:
$contentDbName = “Your.Database.Name”
$webName = “Your web app name”
$url = “http://your.url”
# Get the web application
$webApp = Get-SPWebApplication –Identity $webName
# Create content database
New-SPContentDatabase –Name $contentDbName -WebApplication $webApp
# Create the site
$contentDb = Get-SPContentDatabase –Identity $contentDbName
New-SPSite –Url $url –OwnerAlias “DOMAIN\gavin.mckay” –OwnerEmail “gavin.mckay@domain.local” –ContentDatabase $contentDb –HostHeaderWebApplication $webApp
The important point here is not to use the “-Template <template name>” parameter in New-SPSite. This will break content deployment and you will get a stack of errors about being unable to overwrite content. Deployment failure!
- If you recreate your site collection, you will need to delete your content deployment job and path from the source CA server. The destination site collection id is stored as part of the job/path, and if you recreate your destination site collection it will have a new id. Deployment failure!
- If you delete your content database and recreate it, you will have to do an IISRESET on your CA and web front-ends to get them to resolve properly. You will recognise this by trying to connect to the destination URL and getting the following in your browser:
“HTTP/1.1 200 OK Server: Microsoft-IIS/7.5 Date: Tue, 08 Nov 2011 02:41:04 GMT Connection: close”
SharePoint is confused. Deployment failure!
- If you have Office Web Apps enabled on your source site collection, but not on the destination site collection, you will get:’Microsoft.SharePoint.SPException’ : ‘Could not find Feature MobilePowerPointViewer.’
Deployment failure! Use Site settings, Site collection features, to disable Office Web Apps in the source site collection, then start your deployment job again.
- “The exception thrown was ‘Microsoft.SharePoint.SPException’ : ‘Unable to import the folder _catalogs/fpdatasources. There is already an object with the Id <Guid> in the database from another site collection.'”
Deployment failure! This seems to occur if you have previously had a failed content deployment for a new site collection/content database.
Using your destination CA remove the content database then re-add it again. This will restore the previous empty site collection ready for content deployment.
- Warning “A minor version has been exported with no corresponding major version. It is possible that this item was unpublished then published again. If this item is meant to be published, publish a new version and export/import it again”
This is reasonably straight-forward. Either indivudally (or via a batch job) publish a major version, or turn off major/minor version control for the list/library.
- Warning “Cannot revert to the site definition version of this file”
Currently unknown how to fix this…
- Error “A file with the name [filename] already exists”
Currently unknown how to fix this…
More Detail – What Happens in the Database
The Content Deployment jobs are stored in the source farm SharePoint_Config database. You can view the details in a SQL query via:
Select top 100
id
,classid
,parentid
,name
,status
,version
,properties
FROM [dbo].[Objects]
WHERE Properties like ‘%ContentDeploymentJobDefinition%’
The Properties field is an XML data string that defines the job information.
More Detail – What Happens in ULS
You can view more detail via ULS logging if you enable Verbose logging for the category “Web Content Management” / “Content Deploymet”. Using the ULS Log Viewer will then enable you to see more detail on the process.
After the SharePoint source server packages the deployment files into multiple .cab files, they are individually pushed across to the destination farm. Yo should see ULS entries similar to:
Name=Request (POST:http://destination.sharepoint.local:8080/_admin/Content%20Deployment/DeploymentUpload.aspx?filename=%22ExportedFiles1.cab%22&remoteJobId=%2240ae2be7-f6ee-44c5-a2f0-f456d272a731%22)
After all the CAB files have been pushed across, the source server creates a deployment job on the destination server