Custom Error Pages
Users should see friendly error pages; administrators should see details — but only on the server itself.
On this page · 5 min · Intermediate
On this page
- In simple words
- Learning objectives
- Explanation
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Intermediate
- Updated
- Oct 30, 2026
Related tutorials
Interview questions
In simple words#
Detailed errors are the mechanic’s diagnostic report — useful for staff, scary and risky to show customers. Custom error pages are the polite “sorry, this counter is closed” sign for the public.
- httpErrors
- IIS error page configuration.
- DetailedLocalOnly
- Details on the server, friendly pages for remote users (default).
- existingResponse
- Whether IIS replaces errors produced by your app.
Learning objectives#
- Configure custom error pages
- Show detailed errors only locally
- Work with ASP.NET Core error responses
- Avoid leaking stack traces
Explanation#
errorMode: DetailedLocalOnly (default), Custom (always friendly) or Detailed (always details — never in production).
Map status codes to pages: 404 → /errors/404.html, 500 → /errors/500.html.
existingResponse="PassThrough" keeps responses your app already produced (e.g. JSON ProblemDetails from an API); Replace overwrites them.
For APIs, let the app return JSON errors and avoid IIS HTML error pages.
Code example: Friendly error pages for a website#
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly" existingResponse="Auto">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="404" path="/errors/404.html" responseMode="ExecuteURL" />
<error statusCode="500" path="/errors/500.html" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
<!-- For an API application at /api: keep the app's JSON errors -->
<!-- <httpErrors existingResponse="PassThrough" /> -->
Visitors see the branded 404 and 500 pages; administrators browsing on the server still see detailed IIS errors.
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- DetailedLocalOnly protects details from remote users.
- Existing mappings are removed before adding new ones.
- ExecuteURL serves the page while keeping the status code.
- APIs use PassThrough to keep their JSON errors.
Real-world use case#
A shop shows a helpful 404 page with search and popular categories instead of the default IIS error.
Common mistakes#
Exposes paths, module names and configuration. Use DetailedLocalOnly or Custom.
Search engines index them as real pages. Keep the original status code.
Best practices#
- DetailedLocalOnly or Custom in production
- Branded 404 with search
- PassThrough for APIs
- Keep correct status codes
Remember this#
Details for admins, friendly pages for users.
ExecuteURL keeps the status code.
APIs → PassThrough JSON.
Practice exercise#
Your task: Make an API application keep its own error responses.
Show solution
<system.webServer>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
Mini quiz#
Which errorMode shows details only to requests from the server itself?
Want more? Practise all IIS MCQs · IIS interview questions
My notes#
Saved in this browser.