Apache is the most popular web server in the world. It is well-supported, feature-rich, and flexible. When designing your web pages, it is often helpful to customize every piece of content that your users will see. This includes error pages for when they request content that is not available. In this guide, we’ll demonstrate how to configure Apache to use custom error pages on Ubuntu 14.04.
To get started on with this guide, you will need a non-root user with sudo
privileges. You can set up a user of this type by following along with our initial set up guide for Ubuntu 14.04. You will also need to have Apache installed on your system. Learn how to set this up by following the first step of this guide.
We will create a few custom error pages for demonstration purposes, but your custom pages will obviously be different.
We will put our custom error pages in the /var/www/html
directory where Ubuntu’s Apache installation sets its default document root. We’ll make a page for 404 errors called custom_404.html
and one for general 500-level errors called custom_50x.html
. You can use the following lines if you are just testing. Otherwise, put your own content in these locations:
- echo "<h1 style='color:red'>Error 404: Not found :-(</h1>" | sudo tee /var/www/html/custom_404.html
- echo "<p>I have no idea where that file is, sorry. Are you sure you typed in the correct URL?</p>" | sudo tee -a /var/www/html/custom_404.html
- echo "<h1>Oops! Something went wrong...</h1>" | sudo tee /var/www/html/custom_50x.html
- echo "<p>We seem to be having some technical difficulties. Hang tight.</p>" | sudo tee -a /var/www/html/custom_50x.html
We now have two custom error pages that we can serve when client requests result in different errors.
Now, we just need to tell Apache that it should be utilizing these pages whenever the correct error conditions occur. Open the virtual host file in the /etc/apache2/sites-enabled
directory that you wish to configure. We will use the default server block file called 000-default.conf
, but you should adjust your own server blocks if you’re using a non-default file:
- sudo nano /etc/apache2/sites-enabled/000-default.conf
We can now point Apache to our custom error pages.
We can use the ErrorDocument
directive to associate each type of error with an associated error page. This can be set within the virtual host that is currently defined. Basically, we just have to map the http status code for each error to the page we want to serve when it occurs.
For our example, the error mapping will look like this:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
ErrorDocument 404 /custom_404.html
ErrorDocument 500 /custom_50x.html
ErrorDocument 502 /custom_50x.html
ErrorDocument 503 /custom_50x.html
ErrorDocument 504 /custom_50x.html
</VirtualHost>
This change alone is enough to serve the custom error pages when the specified errors occur.
However, we will add an additional set of configurations so that our error pages cannot be requested directly by clients. This can prevent some strange situations where the text of a page references an error, but the http status is “200” (indicating a successful request).
To implement this behavior, we’ll need to add a Files
block for each of our custom pages. Inside, we can test whether the REDIRECT_STATUS
environmental variable is set. This should only be set when the ErrorDocument
directive processes a request. If the environmental variable is empty, we’ll serve a 404 error:
<VirtualHost *:80>
. . .
ErrorDocument 404 /custom_404.html
ErrorDocument 500 /custom_50x.html
ErrorDocument 502 /custom_50x.html
ErrorDocument 503 /custom_50x.html
ErrorDocument 504 /custom_50x.html
<Files "custom_404.html">
<If "-z %{ENV:REDIRECT_STATUS}">
RedirectMatch 404 ^/custom_404.html$
</If>
</Files>
<Files "custom_50x.html">
<If "-z %{ENV:REDIRECT_STATUS}">
RedirectMatch 404 ^/custom_50x.html$
</If>
</Files>
</VirtualHost>
When the error pages are requested directly by clients, a 404 error will occur because the correct environmental variable is not set.
We can easily produce 404 errors to test our configuration by requesting content that doesn’t exist. To test the 500-level errors, we’ll have to set up a dummy proxy pass so that we can ensure that the correct pages are returned.
Add a ProxyPass
directive to the bottom of the virtual host. Send requests for /proxytest
to port 9000 on the local machine (where no service is running):
<VirtualHost *:80>
. . .
ErrorDocument 404 /custom_404.html
ErrorDocument 500 /custom_50x.html
ErrorDocument 502 /custom_50x.html
ErrorDocument 503 /custom_50x.html
ErrorDocument 504 /custom_50x.html
<Files "custom_404.html">
<If "-z %{ENV:REDIRECT_STATUS}">
RedirectMatch 404 ^/custom_404.html$
</If>
</Files>
<Files "custom_50x.html">
<If "-z %{ENV:REDIRECT_STATUS}">
RedirectMatch 404 ^/custom_50x.html$
</If>
</Files>
ProxyPass /proxytest "http://localhost:9000"
</VirtualHost>
Save and close the file when you are finished.
Now, enable the mod_proxy
and mod_proxy_http
modules by typing:
- sudo a2enmod proxy
- sudo a2enmod proxy_http
Test your configuration file for syntax errors by typing:
- sudo apache2ctl configtest
Address any issues that are reported. When your files contain no syntax errors, restart Apache by typing:
- sudo service apache2 restart
Now, when you go to your server’s domain or IP address and request a non-existent file, you should see the 404 page we set up:
http://server_domain_or_IP/thiswillerror
When you go to the location we set up for the dummy proxy pass, we will receive a “503 service unavailable” error with our custom 500-level page:
http://server_domain_or_IP/proxytest
You can now go back and remove the fake proxy pass line from your Apache config. You can disable the proxy modules if you don’t need to use them elsewhere:
- sudo a2dismod proxy
- sudo a2dismod proxy_http
Restart the server again to implement those changes:
- sudo service apache2 restart
You should now be serving custom error pages for your site. This is an easy way to personalize your users’ experience even when they are experiencing problems. One suggestion for these pages is to include links to locations where they can go to get help or more information. If you do this, make sure that the link destinations are accessible even when the associated errors are occurring.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Greetings.
Even after putting the Files blocks, I am still able to access the error pages directly from the URL. It is not working for me. Ubuntu 18.04 using apache2. Any ideas?
Awesome. Thanks for sharing! One request though: let’s get nerdy and add multilingual support please. In my case, basically I have the documents created in the frontend. I am sending the correct headers. /en/404.html /es/404.html /de/404.html Now I want Apache to redirect based on the Accept-Language accordingly. Is that possible?