Senger CodeLab πŸš€

What is the difference between customErrors and httpErrors

September 29, 2026

πŸ“‚ Categories: Programming
🏷 Tags: Web-Config Iis-7.5
What is the difference between customErrors and httpErrors

Navigating the complexities of error handling in web applications is a critical skill for any developer, ensuring a robust user experience and maintaining application stability. When working with ASP.NET applications hosted on Internet Information Services (IIS), two distinct yet often confused mechanisms come into play for displaying custom error pages: customErrors and httpErrors. While both aim to present a user-friendly message instead of raw system errors, understanding what is the difference between customErrors and httpErrors is fundamental to implementing an effective and secure error management strategy. This distinction impacts how your application responds to various types of failures, from internal application exceptions to server-level HTTP status codes, and mastering it empowers you to control the user’s journey even when things go awry.

Understanding customErrors in ASP.NET

The customErrors configuration is a cornerstone of ASP.NET error handling, specifically designed to manage exceptions that occur within the ASP.NET application domain itself. Configured directly within your application’s web.config file, it dictates how the ASP.NET runtime responds when an unhandled exception is thrown by your code. Its primary role is to prevent sensitive error details, such as stack traces or connection strings, from being displayed to end-users, redirecting them instead to a generic, user-friendly error page.

There are three primary modes for customErrors: “On”, “Off”, and “RemoteOnly”. “On” ensures custom error pages are always displayed, regardless of whether the user is local or remote. “Off” disables custom errors, showing detailed exceptions to everyone, which is typically only used during development. “RemoteOnly” is the most common setting for production environments, displaying custom error pages to remote users while allowing local users (e.g., developers on the server) to see detailed error information for debugging purposes. This distinction is crucial for both security and efficient application monitoring and troubleshooting.

For instance, if your ASP.NET application encounters a database connection error or a null reference exception, customErrors intercepts this application-level error. Instead of displaying a raw .NET exception page, it will redirect the user to a page specified by the defaultRedirect attribute or a specific error page configured for a particular HTTP status code (e.g., a 500 error page). This graceful degradation of service significantly enhances the developer experience and user trust by providing a consistent and non-technical message.

Diving into httpErrors in IIS

In contrast to customErrors, the httpErrors configuration operates at the IIS server level. This powerful feature allows administrators to define custom error pages or responses for specific HTTP status codes directly within IIS, irrespective of the underlying application framework. While often configured in the application’s web.config, its impact transcends the ASP.NET runtime, affecting all content served by IIS, including static files, PHP applications, or even requests that fail before reaching the ASP.NET pipeline.

The httpErrors section within <system.webServer> is responsible for handling errors like 404 (Not Found) for a missing image file, 403 (Forbidden) for unauthorized access to a directory, or even a 500-level error if the application pool crashes before ASP.NET can process the request. It gives you granular control over the content displayed for each HTTP status code. You can specify a static HTML file, a URL on your site, or even a different HTTP response code. This is particularly useful for managing static content errors or preventing default, often unbranded, IIS error pages from being shown to users.

For example, if a user requests a non-existent static CSS file, IIS would typically return its default 404 page. By configuring httpErrors, you can ensure that a custom, branded 404 page is displayed instead, maintaining a consistent user interface. The responseMode attribute (e.g., “File”, “ExecuteURL”, “Redirect”) further refines how IIS handles these errors, providing flexibility in serving content. This server-level error handling is crucial for a complete IIS error pages strategy, ensuring all potential failure points present a professional front.

### Infographic: Visualizing CustomErrors vs. HttpErrors Workflow

This space would typically contain an infographic illustrating the processing flow of a web request and where customErrors and httpErrors intervene in the event of an error.

The Core Difference: Scope and Precedence -----------------------------------------

The fundamental difference between customErrors and httpErrors lies in their scope and the point at which they intervene in the request processing pipeline. customErrors is an ASP.NET specific configuration, primarily dealing with unhandled exceptions that occur within the managed application code, while httpErrors is an IIS server-level configuration that handles HTTP status codes returned by any content served by IIS, regardless of whether an ASP.NET application is involved. This distinction dictates which mechanism takes precedence in various error scenarios, making a combined strategy essential for comprehensive error handling.

When a request comes into IIS, the server processes it through its pipeline. If an error occurs early in this pipelineβ€”for example, a requested file doesn’t exist, or a permission issue prevents accessβ€”IIS handles it directly using its httpErrors configuration. If the request successfully reaches the ASP.NET runtime and an unhandled exception occurs within your application’s code, then customErrors comes into play. However, if the ASP.NET application itself experiences a catastrophic failure (e.g., the application pool crashes) and cannot respond, the error might be caught by Question & Answer :

What is the difference between the customErrors and httpErrors sections of the web.config file in ASP.NET MVC applications?

What are the guidelines for using each section?

*Updated April 2016

The customErrors attribute is used when the .net code is throwing an exception (404, 403, 500 etc) and the httpErrors attribute is used when IIS itself is throwing an exception.

  • /myfakeextensionslessurl –> httpErrors 404
  • /myfakeaspsx.aspx –> customErrors 404
  • /myfakeimage.jpg –> httpErrors 404
  • /throw500.apx –> customErrors 500
  • /throw500 –> customErrors 500

There are a lot of pitfalls trying to configure this correctly. So if you are looking for a quick example, the best 2 options you have are:

Example 1: Using html pages

<system.web> <customErrors mode="RemoteOnly" defaultRedirect="/Error500.html" redirectMode="ResponseRewrite"> <error statusCode="403" redirect="/Error403.html" /> <error statusCode="404" redirect="/Error404.html" /> <error statusCode="500" redirect="/Error500.html" /> </customErrors> </system.web> <system.webServer> <httpErrors errorMode="DetailedLocalOnly" existingResponse="Auto"> <remove statusCode="403" /> <remove statusCode="404" /> <remove statusCode="500" /> <error statusCode="403" responseMode="File" path="Error403.html" /> <error statusCode="404" responseMode="File" path="Error404.html" /> <error statusCode="500" responseMode="File" path="Error500.html" /> </httpErrors> </system.webServer> 

Example 2: using aspx pages

<system.web> <customErrors mode="RemoteOnly" defaultRedirect="/Error500.html" redirectMode="ResponseRewrite"> <error statusCode="403" redirect="/Error403.aspx" /> <error statusCode="404" redirect="/Error404.aspx" /> <error statusCode="500" redirect="/Error500.aspx" /> </customErrors> </system.web> <system.webServer> <httpErrors errorMode="DetailedLocalOnly" existingResponse="Auto"> <remove statusCode="403" /> <remove statusCode="404" /> <remove statusCode="500" /> <error statusCode="403" responseMode="ExecuteURL" path="Error403.aspx" /> <error statusCode="404" responseMode="ExecuteURL" path="Error404.aspx" /> <error statusCode="500" responseMode="ExecuteURL" path="Error500.aspx" /> </httpErrors> </system.webServer> 

And in the aspx error pages you need to do something like this (example 404 page):

<% Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; %> 

Note: Using extension less urls in the customErrors section is not possible!. (without hacks)

One work around is to disable custom errors and let http errors handle the custom page. A friend has created such setup, when I find some time, I will share the code.

Background

A good custom error page will:

  1. Show the real exception when you visit the problem page locally
  2. Show a custom page when you visit the problem page remotely
  3. Will not redirect, but simply show the error page content (because of seo reasons)
  4. Will show the correct status code

So to clarify some options in our config:

  1. <customErrors mode="RemoteOnly". You can specify here: On, Off, RemoteOnly.

    • On = Always show custom error pages
    • Off = Always show the real error
    • RemoteOnly = Show the error locally, but show the custom error page remotely. So we want RemoteOnly for statement 1
  2. <customErrors redirectMode="ResponseRewrite". You can specify here: ResponseRedirect or ResponseRewrite. The ResponseRedirect mode will redirect the error page to the custom error page. For a link crawler (SEO), this will result in 302 -> 500, but you want the link crawler to get a 500 error.

  3. <httpErrors errorMode="DetailedLocalOnly". This the equivalent of the customErrors mode. Options that you have: Custom, Detailed, DetailedLocalOnly.

A good blog post which helped me a lot is: http://benfoster.io/blog/aspnet-mvc-custom-error-pages