ErrorDocument

ErrorDocument and Custom Error Pages That Work

ErrorDocument code target replaces Apache 129 's page for one status code. The target is a local path (an internal redirect that keeps the status code), a quoted string sent as text/html, a full URL, or default, which restores the built-in page:

Custom error pages in .htaccessApache config
# /var/www/example/.htaccess: custom error pages
# Needs: core, mod_alias; AllowOverride FileInfo
ErrorDocument 404 /errors/404.php
ErrorDocument 403 /errors/403.html
ErrorDocument 410 default
Redirect gone /old-catalog

Apache hands the error script the original request in REDIRECT_-prefixed variables. Requested as curl 3,008 -si http://127.0.0.1:8107/no/such/page, this script produced the output below:

errors/404.php, an error page that knows what was asked forPHP
<?php
$asked = htmlspecialchars($_SERVER['REDIRECT_URL'] ?? '/', ENT_QUOTES);
$code  = $_SERVER['REDIRECT_STATUS'] ?? '404';
?>
<!doctype html><title>Page not found</title>
<h1>We could not find <?= $asked ?></h1>
<p>Error <?= $code ?>. Try the <a href="/">home page</a>.</p>
Output
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
...
<h1>We could not find /no/such/page</h1>
<p>Error 404. Try the <a href="/">home page</a>.</p>

The status stays 404, so search engines drop the URL; /old-catalog got Apache's "410 Gone" page (line 5). Link assets by absolute path, since the page appears at whatever URL failed. Traps: with only Indexes allowed, every request got a 500 (ErrorDocument not allowed here). A full-URL target answered 302 Found, losing the 404, and a 401 target must be local or no password prompt appears. A missing target added "Additionally, a 404 Not Found error was encountered". And ErrorDocument 500 never showed for a broken .htaccess or an uncaught PHP exception, which got a blank 500 from PHP itself (PHP).