When you try to access a web page that doesn’t exist, browser shows 404 HTTP status code. However, you may see 200 instead of 404 status code in IIS logs.
Here is the line from my IIS logs. This is actually a failed request that displayed “404 Page not Found” error to the user.
2018-11-27 17:32:28 ::1 GET /app1/kkrr1 – 80 – ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko – 200 0 0 0
Looking for a way to determine user browsers from IIS logs? Check this post out.
What to do if you see 200 instead of 404 status code
The root cause -in my case- is the custom error configuration in the web.config file. I have the configuration below that redirects users to a custom page when there is a 404 error.
<httpErrors existingResponse="Replace" defaultResponseMode="Redirect" errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" responseMode="ExecuteURL" path="/index1.htm"/>
</httpErrors>
Once I changed ExecuteURL
to Redirect
in the responseMode
attribute, IIS started logging 404 errors.
<httpErrors existingResponse="Replace" defaultResponseMode="Redirect" errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" responseMode="Redirect" path="/index1.htm"/>
</httpErrors>
IIS log that shows the correct status code (404) after the change:
2018-11-27 17:33:25 ::1 GET /app1/oopp – 80 – ::1 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko – 404 0 2 46

Background
As mentioned in this blog post, responseMode=”ExecuteURL”
executes the URL in the custom error configuration sends the response to the user Therefore, IIS logs 200 instead of 404 status code. However, responseMode="Redirect”
send 302 response with the custom error page URL to the user. User’s browser makes another request to the given URL.
responseMode=”ExecuteURL”
Source
– path is treated as URL to execute. Response returned by executing the URL is returned to client as response. On successful child execute, client will see a 200 response. Child request will enter the pipeline in the same worker process. If this request is supposed to be executed by some other application pool, IIS core will generate 403.14. When child execute produce some other error, that error code along with child execute response is returned.
– If path starts with “http://”, exact URL specified by path is executed. Hostname has to be current hostname. Else server will produce 404.
– When path starts with “/”, it is assumed as URL for the current site and do a child execute on that.
– If path doesn’t start with “/” or “http://”, server will produce 404 when trying to execute the URL.
responseMode=”Redirect”
– Custom error module blindly uses the path as location header value and send a 302 response. If path is set to “/otherpath/otherpage.htm”, this will be used as the destination and most browsers send this request back to the same host. If you set path to www.iis.net, browsers do the right thing and send the new request to www.iis.net instead.
– IIS doesn’t handle application relative paths both for “Redirect” and “ExecuteURL” as handled by Asp.Net (e.g. ~/error/404.htm).
Still having the issue?
As a generic solution, adding the line below into the custom error page should solve the issue. Make sure to change the file extension to aspx (For example: 404.aspx).
<% Response.StatusCode = 404; %>
References
- What to expect from IIS7 custom error module
- What is the difference between customErrors and httpErrors?
- Web.config – Custom error pages not working
- IIS 404 Custom Error: URL return response code 200 instead
The post IIS is logging 200 instead of 404 status code appeared first on port135.com.