Google and all other search engines say “don’t do soft 404“. The proper way to return a 404 is with a 404 status code and some content that indicates that the requested page is not available. But the key thing is to return the Real 404 HTTP status code and avoid any solution that replaces 404 with 301. This is completely wrong and has the potential to do damage to your site.

How to do this? Well, as always in IT, there are different ways. Here’s how I usually do it.

Add this to web.config:

<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />

Create a new Error controller with a NotFound Action:

public class ErrorController : Controller
public ActionResult NotFound()
Response.StatusCode = 404;//(int)System.Net.HttpStatusCode.NotFound;
return View();

Now when you try to visit something that doesn’t exist you’ll see your custom View:

Don’t forget to create an appropriate view, or you’ll get an IIS 404 error for your Error/NotFound path.

Also, if you’re testing in IIS locally and your application is in a subfolder, you might get only a blank page. This is because IIS is trying to execute the localhost/Error/NotFound URL.

Another, bigger problem with this is that it basically breaks a HandleErrorAttribute 404 handling. So, if you have inherited from HandleErrorAttribute to handle manually thrown 404, your filter will no longer be able to return a custom view, but instead, one defined in web.config will be returned.

Thanks for visiting, feel free to share your thoughts and possibly offer a better solution in the comments.