title: Sitecore 404 page from item
body: <p>Getting Sitecore to respond with a 404 error code, <a href="http://www.partechit.nl/en/blog/2012/11/return-404-status-code-when-itemnotfound-page-is-loaded" rel="nofollow">this blog</a> seems to be the most referenced, where a processor is added to the <code>httpRequestBegin</code> pipeline and the <code>StatusCode</code> is set to 404 while the response is written from the results of a separate request. Like so:</p>
  
  <pre class="lang-cs prettyprint-override"><code>// Request the NotFound page
  string domain = context.Request.Url.GetComponents(UriComponents.Scheme | UriComponents.Host, UriFormat.Unescaped);
  string content = Sitecore.Web.WebUtil.ExecuteWebPage(string.Concat(domain, url));
  
  // Send the NotFound page content to the client with a 404 status code
  context.Response.TrySkipIisCustomErrors = true;
  context.Response.StatusCode = 404;
  context.Response.Write(content);
  </code></pre>
  
  <p>This solution does not work well for me because cookies/security and IP detection is lost when it's the server makes a second request to get the 404 content.</p>
  
  <p>After some back and forth with Sitecore's support, we came up with this code (just a quick sample):</p>
  
  <pre class="lang-cs prettyprint-override"><code>public class MyHttpBeginRequestProcessor : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
  {
      public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
      {
          if (Sitecore.Context.Item != null
          || Sitecore.Context.Site == null
          || Sitecore.Context.Database == null)
          {
              return;
          }
          Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
          Sitecore.Context.Item = master.GetItem("/sitecore/content/home");
          Sitecore.Context.Items["Set404"] = "true";
      }
  }
  public class MyHttpEndRequestProcessor : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
  {
      public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
      {
          if (Sitecore.Context.Items.Contains("Set404"))
          {
              args.Context.Response.StatusCode = 404;
          }
      }
  }
  </code></pre>
  
  <p>And then you put a new processor in the <code>httpRequestEnd</code> pipeline as well as the <code>httpRequestBegin</code> pipeline like so:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&gt;
    &lt;sitecore database="SqlServer"&gt;
      &lt;pipelines&gt;
        &lt;httpRequestBegin&gt;
          &lt;processor type="NewInstance3.Pipelines.MyHttpBeginRequestProcessor, NewInstance3" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']"/&gt;
        &lt;/httpRequestBegin&gt;
        &lt;httpRequestEnd&gt;
          &lt;processor type="NewInstance3.Pipelines.MyHttpEndRequestProcessor, NewInstance3"/&gt;
        &lt;/httpRequestEnd&gt;
      &lt;/pipelines&gt;
    &lt;/sitecore&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>This works perfectly on my local workstation (Win7 x64); however, when I copy the site to a Win2008 x64 server, the default IIS 404 error page is displayed. Setting the StatusCode to 404 on the <code>httpRequestEnd</code> pipeline is causing IIS to display its 404 error rather than the Sitecore Item that I set in the <code>httpRequestBegin</code> pipeline.</p>
  
  <p>Sitecore support says OS shouldn't matter and it works for them on Win2008 server, but I have tried 4 separate Win2008 machines, I have tried a vanilla installation of Sitecore 7.2 rev. 141226 and every time, the default IIS 404 error is displayed.</p>
  
  <p>Any ideas?  Thanks</p>