7

I have successfully set up custom static error pages for IIS7. IIS7 is currently working as a gateway to a Java tomcat application. The issue is that when the 404 error page is served it is served with a HTTP 200 status code header. I would like a way to configure IIS to continue to send a HTTP 404. The error page exists as a static page in the webroot.

This is the main part of my web.config:

<system.webServer>
    <rewrite>
        <rules>
            <rule name="HTTP to HTTPS Redirect" enabled="true">
                <match url="(.*)" />
                <conditions>
                    <add input="{HTTPS}" pattern="off" />
                </conditions>
                <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Found" />
            </rule>
            <rule name="Reverse Proxy" stopProcessing="true">
                <match url="(.*)" />
                <action type="Rewrite" url="http://localhost:8080/{R:1}" />
                <conditions>
                    <add input="{R:1}" pattern="error/*." negate="true" />
                </conditions>
            </rule>
        </rules>
    </rewrite>
    <httpErrors errorMode="Custom" existingResponse="Auto">
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" prefixLanguageFilePath="" path="/error/404.htm" responseMode="ExecuteURL" />
    </httpErrors>
</system.webServer>
Ben Doerr
  • 211
  • 2
  • 6
  • Does the error occur when accessing the page at http://site/error/440.htm, or only when redirected when an error occurs? – Greg Askew Jun 22 '12 at 18:38
  • 1
    Both return a Status Code 200. I would expect going to error/404.htm would return a 200. But consider that foobar.htm doesn't exist. Browsing to foobar.htm would render the error/404.htm (which it does) and set the header status code to 404 (which it does not). – Ben Doerr Jun 22 '12 at 19:02
  • You may want to check: http://stackoverflow.com/questions/434272/iis7-overrides-customerrors-when-setting-response-statuscode or http://stackoverflow.com/questions/347281/asp-net-custom-404-returning-200-ok-instead-of-404-not-found – Greg Askew Jun 22 '12 at 20:18
  • @GregAskew Neither of those address my issue. They both require the application behind IIS to do the reporting of the status code. This is something that any HTTP server should be able to do. And this is much more important for 502 and 503 status codes where the application behind the HTTP server is down. – Ben Doerr Jun 22 '12 at 21:21
  • Quick question: why `responseMode="ExecuteURL"`? You're serving a static file! – Mathias R. Jessen Jun 24 '12 at 20:23

3 Answers3

4

Switch to using responseMode="File" however the trick with this is going to be using relative file paths unless you unlock or set to true system.webServer/httpErrors allowAbsolutePathsWhenDelegated.

Example web.config excerpt:

<httpErrors>
    <remove statusCode="404" subStatusCode="-1" />
    <error statusCode="404" prefixLanguageFilePath="" path="error\404.htm" responseMode="File" />
</httpErrors>
Ben Doerr
  • 211
  • 2
  • 6
  • 1
    It doesn't work for me. It still returns 200 error code – Mike Keskinov May 11 '16 at 17:36
  • Mike, that is too bad. It's been several years since I ran into this issue and haven't really had to use IIS since, it's possible something changed. Please add your answer when you find it so that I can update the correct answer. – Ben Doerr May 12 '16 at 13:29
  • Ben, we just use aspx page where we manually set status code. In some cases it would be much better to use static html file, but unfortunately we haven't found a good solution :( – Mike Keskinov May 12 '16 at 21:57
1

When using executeURL, the file should be something that renders dynamically (a la .asp). The file executed must contain a script that sets the response status code.

Example:

  1. Change your 404.htm to 404.asp
  2. Save the following code at the top of the 404.asp:

<% response.status = "404 Page Not Found" %>

  • Robert, Thanks for your answer. Unfortunately it's been over 8 years since I asked this question, and I have no way to validate if your answer is works or not. Based on the accepted answer above I did eventually figure out that `ExecuteURL` was the problem and moved away from using it in favor of `File`. – Ben Doerr Oct 22 '20 at 12:17
  • You nailed it. Your answer makes absolute sense. – Mojtaba Jul 09 '21 at 08:54
0

Have you tried changing ExecuteURL to Redirect in the responseMode attribute?

<httpErrors existingResponse="Replace" defaultResponseMode="Redirect" errorMode="Custom">
     <remove statusCode="404"/>
     <error statusCode="404" responseMode="Redirect" path="/index1.htm"/>          
</httpErrors>

Reference: https://techcommunity.microsoft.com/t5/iis-support-blog/issue-iis-logs-200-status-code-instead-of-404/ba-p/297652

Kiss
  • 101
  • Vinicius, thanks for your answer. Hopefully it helps others. Unfortunately it's been over 8 years since I asked this question, and I have no way to validate if your answer is works or not. – Ben Doerr Oct 22 '20 at 12:15