In SharePoint 2010, it was quite easy to tell SharePoint to use a custom access denied page that you developed and deployed to the farm instead of the out of the box page. There are many reasons that lead to the need for this, such as changing the text of the message or adding a more dynamic page / form to collect information from the user or perform some other function. Once you build your page and get it deployed, all it took was a call to SPWebApplication.UpdateMappedPage or the PowerShell cmdlet Set-SPCustomLayoutsPage with the proper parameters and you’re off and running. Plenty of posts on the Internet on doing that task so I won’t cover it here.

What I do want to cover, however, is where things stand on this topic with 2013. As of the writing of this post, you can’t do this. Although the same UpdateMappedPage method and Set-SPCustomLayoutsPage cmdlet exists in 2013, there is an identified bug in the product related to the property. The custom location can be set using either of these methods, but SharePoint will not recognize them and will continue to use the out of the box accessdenied.aspx page. I’ve verified this through a Microsoft internal distribution group as well as a support case submitted by me on behalf of one of my clients. Hopefully this gets fixed in a hotfix or CU, but until then you are out of luck.

There are a couple other options, though.

Supported Option: Create an HTTP handler (covered a bit in this forum post) to intercept each request and redirect to your custom page if the server is sending the user to the out of the box accessdenied.aspx page. I don’t like this since it adds overhead to every SharePoint page request.

Wes, good to know. I have gotten a custom login page to work as well, although not using this method. I set the login page through the web application settings in Central Administration. I also noticed after doing that, checking Get-SPCustomLayoutsPage for the login page didn’t reflect my update, even though it was working. I’d be interested in hearing which method you found to be successful.

Hi Ryan/Deepu, Thanks for the update.
We wanted to check with you that April 2014 CU fixed custom access denied page? is there any other configuration or settings need to be done after CU upgrade?
Since we patched this CU at different environments ensured it was upgraded successful, but we didn’t get any luck in this issue :(.. its still taking us to the OOB Access Denied Page not to our Custom Access Denied page (the issue still persist).

An ideas, Ryan, what those people did to get it working? We’ve installed the July 2014 CU (and SP1), but I’m not seeing any change. It’s ignoring the path given by Get-SPCustomLayoutsPage for both AccessDenied and Signout (quite likely other or all page types are affected).

No ideas why, but the CU fixing this issue kicked in after a few days. I’m certainly not going to complain–much. At least it’s now working! Well, working for the most part. Sites using the 2013 UI are getting the custom Access Denied page, but sites using the 2010 UI are not. Can’t find anything about this dichotomy. Not even finding how it is SharePoint substitutes your custom page with the out-of-box page when the URL isn’t changing when it does work (SP2013 UI).

As it turns out, the question about the UI is quite important. If your site is using the 2013 UI, you’re fine: By default Get-SPCustomLayoutsPage, Set-SPCustomLayoutsPage, and Microsoft.SharePoint.Administration.SPWebApplication.UpdateMappedPage(…) work with a CompatibilityLevel = 15. That’s right, CompatibilityLevel! There is an undocumented parameter on these cmdlets and method (presumably added with the April 2014 CU). If your site is using the 2010 UI, you’ll need to specify a CompatibilityLevel = 14 when using these cmdlets or method. Just be sure to give the correct path for the correct hive/UI: The path must start with “/_layouts/15/” for the 2013 UI (CompatibilityLevel = 15, or omitted), and must start with “/_layouts/” for the 2010 UI (CompatibilityLevel = 14).

Just be sure you deploy your custom pages to both hives. For me, I had packaged the pages in a farm solution. Just needed to deploy the pages to both hives by specifying CompatibilityLevel = All when executing Install-SPSolution. (Unfortunately, there’s no way to do this from the deployment in CA.)

Of course, this means you are able to have different pages for each of the mapped pages for each of the hives. Want one Access Denied page for the 2010 UI and a different one for the 2013 UI? No problem!