X marks the spot

random commentary on life, the universe, and anything

WordPress, permalinks, and 404 errors


One of the things that has been on my WordPress to-do list has been changing from Default (http://localhost/?/p=123) permalinks to more SEO-friendly ones (http://localhost/sexy-permalink) for a couple of academic websites that I support.

WordPress is normally so ridiculously simple to use, even self-hosted, but getting this change to work took a fair amount of Google spelunking.

The Rackspace CentOS 6 virtual server that I am running this particular site on uses apache VirtualHosts to map each WordPress site to a separate directory.

# site1.org
     DocumentRoot /var/www/html/site1
     ServerName site1.org

# site2.org
     DocumentRoot /var/www/html/site2
     ServerName site2.org

Things that didn’t work for me but should be tried:

  1. Deactivating plugins (to avoid WP conflicts)
  2. Verifying that apache has loaded mod_rewrite (it was)
  3. Verifying that the root directory for the WordPress instance had a .htaccess file (it did)
  4. Verifying that .htaccess has something like this: (it did)
    <IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteBase /
     RewriteRule ^index\.php$ - [L]
     RewriteCond %{REQUEST_FILENAME} !-f
     RewriteCond %{REQUEST_FILENAME} !-d
     RewriteRule . /index.php [L]

Note: I also ran into the problem of this code disappearing (apparently) randomly from .htaccess. Turns out that when changing Permalinks from Default to posts (or any other permalink setting actually), WordPress tries to modify the .htaccess file. Because my permissions were set 644 (rw-r–r–) and WordPress runs as the owner, when toggling modes back and forth (on/off), WordPress was editing/re-editing the file. Setting permissions to 444 (r–r–r–) fixed that.

What worked:

The sub-directory in which WP was installed had the right .htaccess, but httpd.conf was not allowing apache to use that file. Specifically AllowOverride was not set to All.

Since I’m using CentOS, my httpd.conf file is in /etc/httpd/conf/. Using vi, I searched for anywhere AllowOverride was set:

# Each directory to which Apache has access can be configured with respect
# to which services and features are allowed and/or disabled in that
# directory (and its subdirectories).
# First, we configure the "default" to be a very restrictive set of
# features.
<Directory />
    Options FollowSymLinks
    AllowOverride None

This is good. I want my root directory to be locked down. It’s the next section that is the one I want.

# This should be changed to whatever you set DocumentRoot to.
<Directory "/var/www/html">

# Possible values for the Options directive are "None", "All",
# or any combination of:
#   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
# The Options directive is both complicated and important.  Please see
# http://httpd.apache.org/docs/2.2/mod/core.html#options
# for more information.
    Options Indexes FollowSymLinks

# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
#   Options FileInfo AuthConfig Limit
    AllowOverride None

# Controls who can get stuff from this server.
    Order allow,deny
    Allow from all


Again, this is fine. Now I need to add exceptions for the specific directories.

# allow .htaccess files for wordpress directories
<Directory "/var/www/html/site1">
    AllowOverride All


Reference that helped:
Setting Up Pretty Permalinks in WordPress Using htaccess and mod_rewrite on Linux (CentOS 6)

Leave a Reply