A Helpful Guide to Creating Custom Error Pages in ASP.NET

Depending on how you plan to use your website, creating custom errors can be very challenging. This is often due to limited documentation, confusion on forums, and windows authentication. Check out the tutorial below to get a better understanding of how custom errors work.

Catching Application Thrown Messages (Legacy)

You can catch custom errors several ways in ASP.NET. The first method, called CustomErrors in the web.config, catches errors from within the application. These errors are typically caused by an exception being thrown by your application. It is important to note that this method will not catch a broken link (404) or a user authentication error (401). Additionally, this is the old legacy method for anything pre-IIS7; therefore, it is not highly recommended.

The configuration above gives you the option to set global custom error properties as well as specify which error codes to catch. Remember, the CustomErrors should reside under the system.web section of the web.config. The defaultRedirect, redirect, and statusCode sections are fairly straightforward. These specify what URL you choose to redirect to relative to your application and what status code you want to catch.

The redirect mode allows you to set custom errors on, off, or remote only. Remote only means that the standard Microsoft error will be displayed on localhost, while everyone else will get the custom error page. Redirect mode also allows you to overwrite the current page so that the URL will either remain the same or redirect you to the error page URL.

Catching Errors with Executable Error Pages and Redirects (Current)

The second method of catching custom errors in asp.net is by HttpErrors. It is important to note that unlike legacy CustomErrors, HttpErrors are actually executed by IIS directly rather than the application. This provides a much wider sweep of error catching. The diagram below shows that CustomErrors only catches a fraction of the potential errors from your website or web application.

Like CustomErrors, HttpErrors allow you to either rewrite the response (execute) or redirect the response. An execute will replace the content of the page, whereas the redirect will navigate to a new page. The response mode is called execute because you are allowed to create error pages as aspx or cshtml. This allows you access to the exception being thrown and format that error message the way that you want or perhaps do some logging.

Global and Error Specific Options

Again, we have some global options and error specific options. For global, we have the following settings:

errorMode: allows you to show custom errors all the time (Custom), show only for remote users (DetailedLocalOnly), or never show custom errors (Detailed).

existingResponse: allows you to always replace the exception thrown with an error page (Replace), let whatever gets thrown to pass through (Passthrough). You would only use this if you were creating your own error handling and didn’t want IIS to interfere. The last option is auto.

defaultPath: the default error page.

defaultResponseMode: you have the option to execute the page (ExecuteURL), redirect (Redirect) or you can return a static file like .htm (File). The File mode will be useful later.

For individual error options we have:

statusCode: the error code you wish to catch.

Path: the path to your error page. It must have forward slashes and the first forward slash represents the relative path of your application so far.

responseMode: you can overwrite the global response mode here.

subStatusCode: the sub status code you wish to catch. If not specified will cover them all in most cases.

You must also remove the current status code error before you add a new one in the configuration. Specifying “-1” for subStatusCode removes all sub-status errors for that status code. When you deploy your website/web application, you can verify that the proper error page configuration was loaded by going to IIS Manager, then selecting your application and opening Error Pages.

Catching Errors with Static Pages (Current)

The third method focuses on catching errors with static pages using the responseMode=”File” configuration. In most cases, it is more advantages to execute or redirect. However, that is not the case with authentication errors; specifically windows authentication. Before we explore details on catching authentication errors, we’ll look at how windows authentication works.

Windows Authentication

Windows authentication works with cooperation from the client browser. The client gets a token from active directory that is passed to the server. The server then verifies that the token is good and lets the user have access. However, ASP.NET does not redirect the user to a login page every time it needs to authenticate. Instead, it returns a 401 page until the client provides the proper token. It is up to the browser to hide the error page and show the user the windows login box (if the user is off network). Or resend the request with the token. Please see the diagram at the end of this blog post for an outline of the process.

Windows Authentication and Custom Errors

Since it is up the client browser to know when it needs to supply the token, we need to ensure the client receives the 401 error in the header. However, if you execute or redirect to an error page, the error will be wiped because you are essentially handling the error. This means that the user will get a 401 error message, but the browser will be unaware that it needs to supply the token since the header has been cleared. This is due to the fact that you are now returning a different page from when the error happened. You cannot set the header back to the 401 error as that would cause an infinite loop. To get around this, you need to return a static file that does not get executed and cannot create errors of its own. IIS will not wipe the header for a static file, so you will need to create static file 401 error pages if you want to use windows authentication and custom errors pages.

Static files are not as flexible as executing code, so you need to make sure that you specify every sub status code. You also need to have a different file path syntax. When executing a file, the format is: /folder name/file name. For static files, the format is: folder name\file name. Please note that static files require a backslash and have an assumed first backslash. Additionally, if it is not entered in this exact format it will not work.

Creating custom errors can be challenging for a variety of reasons. However, this tutorial should help you gain a better understanding of how custom errors work.


This blog post was written by Joseph Van Den Berg.