Custom 404 page sends 200 status code

Learn custom 404 page sends 200 status code with practical examples, diagrams, and best practices. Covers php, http-status-code-404, http-status-codes development techniques with visual explanations.

Fixing Custom 404 Pages That Return a 200 OK Status Code

Hero image for Custom 404 page sends 200 status code

Learn why your custom 404 error page might be sending a 200 OK status and how to correctly configure your server and application to return the appropriate 404 Not Found HTTP status code.

A common issue developers face when implementing custom 404 error pages is that the server, despite displaying the custom error content, still returns an HTTP status code of 200 OK. This can lead to several problems, including poor SEO, incorrect analytics, and confusion for automated tools that rely on proper HTTP status codes. This article will explain why this happens and provide solutions for various server environments and programming languages.

Understanding HTTP Status Codes and 404 Errors

HTTP status codes are three-digit numbers returned by a web server in response to a browser's request. They indicate whether a particular HTTP request has been successfully completed. The 2xx series (e.g., 200 OK) indicates success, while the 4xx series (e.g., 404 Not Found) indicates client errors. A 404 Not Found status specifically means that the server could not find the requested resource. When a custom 404 page is served with a 200 OK status, it tells search engines and other clients that the requested (non-existent) URL is actually a valid page, which can lead to those non-existent pages being indexed.

flowchart TD
    A[User requests URL] --> B{Resource exists?}
    B -->|Yes| C[Server returns 200 OK + Content]
    B -->|No, but custom 404 configured| D[Server serves custom 404 page]
    D --> E{Is HTTP status set to 404?}
    E -->|No, default 200 OK| F[Problem: 200 OK with 404 content]
    E -->|Yes, explicitly set 404| G[Correct: 404 Not Found with 404 content]

Flowchart illustrating the process of serving a 404 page and the potential for incorrect status codes.

Common Causes for 200 OK on 404 Pages

The primary reason a custom 404 page might return a 200 OK status is often due to how the server or application is configured to handle errors. Instead of explicitly telling the server to send a 404 Not Found header, the server might simply process the custom error page as a regular request, resulting in a default 200 OK status. This can happen in various scenarios:

  • Server Configuration: Web servers like Apache or Nginx might be configured to internally redirect to the custom 404 page without changing the HTTP status code.
  • Application Logic: Frameworks or custom PHP scripts might include the 404 page content using include() or require() after determining a resource is not found, but without sending the header("HTTP/1.0 404 Not Found") directive.
  • CMS/Framework Defaults: Some content management systems or frameworks might have default error handling that prioritizes displaying content over setting the correct HTTP status.

Solutions for Correct 404 Status Codes

The solution depends on your server environment and how your custom 404 page is implemented. Below are common approaches for different setups.

PHP

<?php
header("HTTP/1.0 404 Not Found");
// Or for newer PHP versions and HTTP/1.1+
// http_response_code(404);
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>404 Not Found</title>
</head>
<body>
    <h1>Oops! Page Not Found</h1>
    <p>The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.</p>
    <p><a href="/">Go to Homepage</a></p>
</body>
</html>

Apache (.htaccess)

ErrorDocument 404 /404.php
# Ensure the 404.php file explicitly sets the 404 header if not handled by Apache
# Or, if you want Apache to handle the status code directly with a static HTML file:
# ErrorDocument 404 /404.html

When using ErrorDocument 404 /404.html, Apache will automatically send the 404 Not Found status code along with the content of 404.html. If you use a dynamic script like 404.php, ensure the PHP script itself sets the header.

Nginx

server {
    listen 80;
    server_name example.com;

    root /var/www/html;
    index index.html index.htm index.php;

    error_page 404 /404.html;
    location = /404.html {
        internal;
    }

    # If using a PHP script for 404, ensure it sets the header
    # error_page 404 /404.php;
    # location = /404.php {
    #     internal;
    #     fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    #     include fastcgi_params;
    #     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    # }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }
}

Nginx's error_page directive, especially with internal; for the error page location, is designed to serve the content with the correct status code.

1. Identify the Problem

Use your browser's developer tools (Network tab) or an online HTTP header checker to confirm that your custom 404 page is indeed returning a 200 OK status code instead of 404 Not Found.

2. Locate Your 404 Handler

Determine where your custom 404 page is being served from. Is it a static HTML file, a PHP script, or handled by your web server's configuration (Apache .htaccess, Nginx error_page)?

3. Implement the Fix

Apply the appropriate solution based on your server environment and programming language, as detailed in the 'Solutions for Correct 404 Status Codes' section above.

4. Verify the Solution

After implementing the changes, re-check the HTTP status code for a non-existent URL using the same tools from step 1. Confirm that it now correctly returns 404 Not Found.