Troubleshooting IIS 500 Errors Using httpErrors
It’s not uncommon for users to encounter a 500 – Server Error while browsing an application hosted on IIS. This typically indicates something went wrong on the server side. But what exactly? To start, IIS logs an entry with a substatus code in its log files—these codes are key to diagnosing what went wrong. Additionally, you might find relevant information in the System or Application event logs. But what if no events are logged there? That’s when things get tricky, and the issue becomes harder to troubleshoot. In such cases, understanding how to work with httpErrors in IIS can be helpful.
customErrors vs. httpErrors: What’s the Difference?
Before jumping to the solution, let’s understand the difference between customErrors and httpErrors, as they are often confused.
In simple terms:
customErrors handles exceptions thrown by .NET code (like 404, 403, or 500 errors).
httpErrors deals with errors that IIS itself generates, not those from the application.
customErrors is part of the System.Web section, which governs how .NET errors are managed. Here’s a sample of customErrors in a web.config:
<configuration>
<system.web>
<customErrors defaultRedirect=”GenericError.htm” mode=”RemoteOnly”>
<error statusCode=”500″ redirect=”InternalError.htm”/>
</customErrors>
</system.web>
</configuration>
On the other hand, httpErrors belongs to system.webServer, part of the IIS configuration. Here’s an example of httpErrors in the IIS configuration:
<system.webServer>
<httpErrors errorMode=”Custom” defaultResponseMode=”ExecuteURL”>
<error statusCode=”400″ path=”/iisstart.htm” responseMode=”ExecuteURL” />
</httpErrors>
</system.webServer>
Is it an IIS or .NET Error? How to Tell?
When troubleshooting a 500 error, the first step is to determine whether it’s originating from the IIS pipeline or the .NET application. To isolate this, enable Failed Request Tracing (FREB) logs for the website in question. These logs provide detailed information about the request’s journey through the IIS pipeline and reveal which module is responsible for the error.
How to Enable and Read FREB Logs: Reading FREB logs can give you valuable insights into where the problem lies. You can find a step-by-step guide on enabling and analyzing these logs on Microsoft’s community hub.
If the 500 error is coming from the .NET pipeline, you’ll want to adjust the customErrors settings. One common approach is to disable customErrors temporarily to get more detailed error messages. This is especially useful when debugging issues in development or staging environments.
Here’s how to set the customErrors mode:
On: Custom error pages are enabled. Without a defaultRedirect, users will see a generic error page.
Off: Disables custom error pages. Detailed ASP.NET errors are shown to both local and remote clients.
RemoteOnly: Custom error pages are shown to remote clients, while detailed errors are visible to the local server. This is the default setting.
For example:
<configuration>
<system.web>
<customErrors mode=”Off” />
</system.web>
</configuration>
Tweaking httpErrors for IIS Modules
If the error is coming from an IIS module (i.e., not related to your .NET application), tweaking the httpErrors settings is the way to go. One useful trick is to configure IIS to pass through the existing response rather than suppress it. This lets you see the full error, which can provide more context for debugging.
Here’s how to enable the pass-through configuration for httpErrors:
<configuration>
<system.webServer>
<httpErrors existingResponse=”PassThrough” />
</system.webServer>
</configuration>
This setting prevents IIS from masking the actual error response, making it easier to pinpoint the root cause.
Your case might not exactly be this, so to learn more about httpErrors? Grab more details from here. HTTP Errors <httpErrors> | Microsoft Learn
Microsoft Tech Community – Latest Blogs –Read More