WordPress: 404 After Changing Permalinks

Whew! This took me way longer than it should have. Long story short, I was missing the rewrite module on Apache, my Apache configuration file needed an update and my Apache virtual host setup was messed up! I’m not positive at what point I broke my virtual host setup but I knew I had made a mistake when I ran the command below and saw a backup file under my virtual hosts. Sadly, I only came across the command below after a few hours of researching the issue. Let’s blame it on the fact I had not had a morsel of food for seven hours.

apache2ctl -S

First we must verify that the rewrite module in Apache is enabled. If the module is not enabled we will not be able to run the directives under our WordPress site’s .htaccess file. If the module is already enabled on your server, you will receive a message stating so. It will also be visible under /etc/apache2/mods-enabled as rewrite.load. Run the commands below to enable the module and restart Apache.

sudo a2enmod rewrite
sudo service apache2 restart

After verifying the rewrite module is enabled, check to see if there is still a 404 error on your pages. If there isn’t, great! Else, we continue, when you change the permalink format through your WordPress admin console it inserts rewrite rules to the hidden file .htaccess in your WordPress directory. .htaccess files contain overrides or additional information about your site configuration. Versions 2.3.9+ of Apache, by default do not allow .htaccess files to override the configuration specified under /etc/apache2/apache2.conf. Apache’s main configuration file also includes any configurations you may have written for any enabled virtual hosts. Below is a snippet from the default Apache configuration file.

# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted

The AllowOverride None directive above is stating that for directory /var/www/ do not allow the server configuration to be overwritten through the use of .htaccess files. There are two reasons for this logic 1) performance gain and 2) security. WordPress’s default behavior is to edit the .htaccess file when you make changes to the permalink format so you may choose to keep .htaccess but keep in mind Apache does not recommend the use .htaccess if you have access to the main configuration file.

The AllowOverride directive accepts three different values; 1) None, 2) All, and 3) Directive Name. If you choose to keep using the .htaccess file, the third option allows for better security than simply entering All by allowing us to enter which directives can be overwritten. For the purposes of this particular issue we will be using the value FileInfo so we may make use of the rewrite module but visit the official Apache documentation for more information on the directive names available and how to use them.

Below is the code you want present in your Apache configuration file so WordPress’s .htaccess may be able to rewrite your URL’s and serve your pages.

       <Directory [YOUR_DIRECTORY_PATH]>
                Options Indexes FollowSymLinks
                AllowOverride FileInfo #Alternatively, use AllowOverride All
                Require all granted

If you would like to remove the .htaccess file and instead include your rewrite logic in your configuration file you will need to include the rewrite directives within the Directory tags as shown below.

       <Directory [YOUR_DIRECTORY_PATH]>
                Options Indexes FollowSymLinks
                AllowOverride FileInfo #Alternatively, use AllowOverride All
                Require all granted
                RewriteEngine On
                RewriteBase /
                RewriteRule ^index\.php$ - [L]
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_FILENAME} !-d
                RewriteRule . /index.php [L]

After editing your configuration files make sure to restart your Apache server to make our changes active. By this point, the 404 error on your WordPress pages should be gone.

If it is not and you are making use of virtual hosts, I urge you to verify that your Apache virtual host configuration is correct. I spent quite a while with this issue because I had a larger underlying issue with my virtual host configuration. I was able to identify the issue by not resorting to making changes to apache2.conf when I felt positive the changes on my virtual host configuration file were supposed to work. My particular issue was a file I had renamed as a backup was still linked as a virtual host and was occupying the same server name as the new file I thought was the active virtual host. Both my backup and newer file had the same server name specified. I removed my backup from the server entirely and it worked. My brain was toasted.

Leave a Reply

Your email address will not be published.