How to Implement a Custom 404 Error Alert System in WordPress Without Plugins

In this tutorial, you will learn how to enhance your WordPress site’s error-handling capabilities by setting up a custom 404 error page that sends email alerts to the site administrator when a page is not found. This proactive approach helps administrators stay informed about potential issues, facilitating prompt investigation and resolution.

Before proceeding with any customizations in WordPress, it’s essential to set up a child theme. A child theme acts as a safe and efficient way to make modifications without affecting the parent theme. If you haven’t set up a child theme yet, follow this tutorial on How to Create a Child Theme for Customization. It will guide you through the process and ensure that your customizations remain intact even after theme updates.

Locate or Create the 404.php File

Begin by navigating to your child theme directory. If you already have a 404.php file, open it. If not, consider copying the 404.php file from your parent theme to your child theme for customization. Within the 404.php file, insert the following code snippet at an appropriate location:

// Set HTTP response code to 404
status_header( 404 );

// Retrieve site information
$site_name   = get_bloginfo( 'name' );
$admin_email = get_bloginfo( 'admin_email' );

// Capture the essence of the requested URL
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
	// Capture the requested URI and sanitize it
	$request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) );
} else {
	$request_uri = 'undefined';

if ( isset( $_SERVER['HTTP_HOST'] ) ) {
	// Capture the HTTP host (domain) and sanitize it
	$http_host = esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] ) );
} else {
	$http_host = 'undefined';

// Craft the error URL with Yoda conditions
if ( 'undefined' !== $request_uri && 'undefined' !== $http_host ) {
	$error_url = "https://$http_host$request_uri";
} else {
	$error_url = 'undefined';

if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
	// Capture the HTTP referer and sanitize it
	$referrer = esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) );
} else {
	$referrer = 'undefined';

if ( isset( $_SERVER['QUERY_STRING'] ) ) {
	// Capture the query string and sanitize it
	$query_string = sanitize_text_field( wp_unslash( $_SERVER['QUERY_STRING'] ) );
} else {
	$query_string = 'undefined';

if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
	// Capture the remote IP address and sanitize it
	$ip_address = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
} else {
	$ip_address = 'undefined';

if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
	// Capture the user agent and sanitize it
	$user_agent = sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) );
} else {
	$user_agent = 'undefined';

// Engrave the current time using gmdate to avoid timezone issues
$log_time = gmdate( 'F jS Y, h:ia', time() );

// Craft the email message
$message = "
ERROR URL: $error_url
REFERRER: $referrer
QUERY STRING: $query_string
REMOTE ADDRESS: $ip_address
USER AGENT: $user_agent
TIME: $log_time

// Create a distinctive email subject
$email_subject = "404 Error Alert: $site_name - $error_url";

// Set the stage with email headers
$headers = array(
	'From: ' . $admin_email,
	'Content-Type: text/plain; charset=UTF-8',

// Deliver the email using wp_mail
wp_mail( $admin_email, $email_subject, $message, $headers );

Code language: PHP (php)


  • The code begins by setting the HTTP response code to 404 using status_header(404).
  • Site information, such as the site name and admin email, is retrieved using get_bloginfo.
  • The code captures essential details of the requested URL, such as the URI, HTTP host, and HTTP referer, while sanitizing and handling undefined values.
  • The error URL is crafted using Yoda conditions to handle undefined values gracefully.
  • Various server variables, including query string, remote IP address, and user agent, are captured and sanitized.
  • The gmdate function is used to format a GMT/UTC date and time. Unlike date, gmdate always uses the GMT/UTC time regardless of the server’s timezone setting.
    • To set the timezone for your specific location (e.g., Belgium), you can use the date_default_timezone_set function. In the example, the timezone is set to ‘Europe/Brussels’, which corresponds to Central European Time (CET). This ensures that the displayed time is adjusted according to the specified timezone, preventing potential issues related to server timezones. Adjust the timezone string as needed based on your location.
  • An email message is crafted, including details such as the error URL, referrer, query string, remote address, user agent, and timestamp.
  • A distinctive email subject is created, incorporating the site name and error URL.
  • Email headers are set, including the ‘From’ address and content type.
  • The email is then delivered using wp_mail to the site administrator’s email address.

Save, Test, and Verify Email

Save the modifications made to the 404.php file. Subsequently, conduct a test by intentionally accessing a non-existent page on your website. Following the test, check the specified admin email for the 404 error alert. Ensure that both the subject and content of the email contain the anticipated information.

That’s it! You’ve successfully implemented a custom 404 error alert system for your WordPress site directly within the 404.php file of your child theme, avoiding the use of plugins.

Leave your feedback and help us improve ๐Ÿถ

We hope you found this article helpful! If you have any questions, feedback, or spot any errors, please let us know in the comments. Your input is valuable and helps us improve. If you liked this article, please consider sharing it with others. And if you really enjoyed it, you can show your support by buying us a cup of coffee โ˜•๏ธ or donating via PayPal ๐Ÿ’ฐ.

More free knowledge, because why not?

Your thoughts matter, leave a reply ๐Ÿ’ฌ

Your email address will not be published. Required fields are marked *