404’s on WordPress Permalinks (IIS with ISAPI Rewrite)

So, one day I decided to start a blog. I had available a windows server with IIS 6.0 and I PHP enabled it some time ago. After some looking around I found WordPress was what I wanted to use.  The whole installation works like a charm and with not much hassle. But for SEO reasons, I wanted to use WordPress’s permalink (common structure)  feature. For this to work you need a URL rewrite solution. Apache can use mod_rewrite here, but on IIS we could use for example Helicon’s ISAPI Rewrite Lite. I installed it following Kyle Caulfields manual. But… it didn’t work for me unfortunately.

Update (March 25th, 2011): After updating WordPress from version 2.9.2 to version 3.1 I had this problem again. See the bottom of this page for how I fixed that.

First of all, lets mention I had problems with WordPress 2.9.2 combined with ISAPI_Rewrite3 Lite on IIS 6.0. I don’t know if the problem occurs on other combinations of versions on the previously mentioned software. I’m going to tackle two problems I had with 404’s. First a 404 that came from WordPress and next a 404 from IIS.

404 from WordPress

I installed everything as mentioned above on my development server just as as Kyle Caulfield explained, I added the following code to the httpd.conf file from ISAPI_Rewrite3 Lite:

RewriteEngine on
RewriteBase /

#Exclude javascripts/stylesheets/images etc from rewriting
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

#Perform rewriting
RewriteRule ^(.*)$ index.php?p=$1 [NC,L]

After restarting IIS I could reach my blog’s home page, but as soon as I tried to go to an article I got a 404 page not found from WordPress. What is going wrong here? My assumption was that the rewrite ISAPI plugin was reached because otherwise I’d expected a 404 from IIS here. It must be the rewrite rule. To find out what could be going wrong you need to have some feedback from the system. I added the following code inside {wordpress}/index.php just below the first define statement:

echo "<pre>";
print_r($_SERVER["REQUEST_URI"] );
echo "</pre>";

This piece of code prints out the PHP server REQUEST_URI variable which tells us what the RewriteRule passes on to PHP. I went back to my browser and refreshed my page. What I found was that the rewrite rule was rewriting my URL’s to something like /index.php?p=index.php/my-first-article. Well, that’s not gonna work. The trick is now to fix the rewrite rule just so that it will give me /index.php/my-first-article. I tested that this approach works by placing it in the browser’s location bar and hitting enter. This works, so I know what I should work towards.

Back to the Rewrite Rule:

#Perform rewriting
RewriteRule ^(.*)$ index.php?p=$1 [NC,L]

I saw index.php itself getting picked up by the Regular Expression part ^(.*)$. I’m not going into explaining regex’s here, you could google it :). Let’s update it just so it won’t pick up index.php anymore:

#Perform rewriting
RewriteRule ^(index\.php)*(.*)$ index.php?p=$2 [NC,L]

In short what I’m doing here is creating an extra regex group by surrounding to be matched values with ( and ). This is group 1. Behind it was the old group which now becomes group 2. This 2nd group is the info we need for our rewritten URL. To use this group we need to update the digit in $1 to $2.

After restarting IIS you’ll find out you’ll get the following rewritten URL: /index.php?p=/my-first-article. This is not working since WordPress expects an article number behind ?p=. Lets fix this now:

#Perform rewriting
RewriteRule ^(index\.php)*(.*)$ index.php/$2 [NC,L]

As you can see I changed the ?p= part to a slash. I restarted IIS again and it worked! Time to place my development server version to my live server…

404 from IIS

I did the exact same as mentioned above (installing WordPress and the whole URL rewrite setup) but now on my live server… I again got a… 404… WTF?! This time the 404 came from IIS and not from WordPress. What do I have to fix this time? My assumption now is that the HTTP request doesn’t reach WordPress’s PHP files at all and that the problem lies with IIS and the ISAPI rewrite filter.

I started googling and found that the problem could be the IIS Metabase was somehow corrupted. I installed a tool called IIS MetaBase Explorer. There’s also a Metabase Explorer from Microsoft which you can probably use in the same way.

I first created a backup of the MetaBase with IIS Metabase Explorer (top left button with the red arrow). Now I removed all references  I found to the ISAPI Rewrite filter (see image below) by simply clicking on them and hitting the delete button. If you installed the ISAPI Rewrite filter correctly you should be able to find it in a root folder called Filters and in a folder called filters inside a folder with a number. You can find the correct site by clicking on the numbers and search inside the key/value pairs for you website’s name:

IIS Metabase Explorer

When this was done I removed and reinstalled ISAPI Rewrite3 Lite. Remember to copy the file httpd.conf to your desktop or another place before reinstalling and then place it back in the install dir. I restarted IIS and… voila… you are looking at the result.

Upgrading WordPress 2.9.2 to WordPress 3.1

At some point I updated WordPress from version 2.9.2 to version 3.1. Al went quite well, so I zipped my backup files to store them and probably (hopefully) never to ever need them ;). WordPress was doing fine when just checking my blog on the homepage but then I tried an article… Oh no, not again! I got infinite redirects. After some googling I found people recommending the following plugin: Permalink Fix & Disable Canonical Redirects Pack. It worked for me, so if you fixed this problem before according to my post above, this might help you again. Happy blogging!

15 gedachten aan “404’s on WordPress Permalinks (IIS with ISAPI Rewrite)”

  1. Hi Rafael M, that’s difficult to say. What kind of access do you have then? You could ask your provider how you should fix it with the tools that are provided by them or ask them to fix this for you (and perhaps all their other customers). If they happen to get the same problem as I had, I hope Google will bring them to this article 😉

  2. I got Kyle Caulfields solution working fine but for some reason it breaks the .aspx page that use AJAX on my website. I get JS errors about ‘sys’ and AJAX library wont load or function.

    Any ideas why this coukld be happening when I use the simple code

    RewriteEngine on
    RewriteBase /blog
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(index\.php)*(.*)$ /blog/index.php/$2 [NC,L]

    It’s killing my brain!

  3. Hi lexx2gee, I understand the frustration you may have with this kind of stuff ;).

    You say you work with .aspx pages? So why are you using the RewriteRule with .php in it then? Shouldn’t you at least change this to .aspx?

    I don’t know if this is the case, but in your HTML code, how do you reference external .js and .css files? If you do this with (non root) relative URL’s (src=”script.js”) instead of absolute URL’s (src=”http://yourdomain.com/script.js”) this could very well break since your browser now uses the redirected URL structure as the base for the relative URL’s.

    You can try if the use of an absolute path fixes your problem just so you know this solves it and then add rewrite rules to make your relative URL’s work again.

    Hope this’ll fix it for you!

  4. DUDE !!!! You rule!

    The very key for working with wordpress under shared hosted iis6 and isapi rewrite is to use that line:

    RewriteRule ^(index\.php)*(.*)$ index.php/$2 [NC,L]

    That worked like a charm.

    Thanks a lot!

  5. If anyone is still using IIS6 and having this problem, in your ISAPI mod-rewrite under Engine Settings, check the box for Keep original “Host” header. I was getting 404 errors from IIS before making this change. After that the rewrite rules you gave worked great!

  6. i am not a developer, but got into a situation where i had to set up a windows server 2003 r2 with PHP, IIS6, and MySQL. I used the Helicon ISAP rewrite and all was going well…until i looked at it on IE. For whatever reason, I am getting a #? before my page url and the page wont fully load. On some pages, it just loads a youtube video in a lightbox.

    Not sure if you could throw me a suggestion as to a solution. This is working perfectly on a mac (safari/firefox), and chrome on a PC, just not on a pc IE or firefox.

    Permalinks set to custom structure: /%postname%/

    httpd.conf is set to:

    RewriteEngine on
    RewriteBase /pivotology/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(index\.php)*(.*)$ index.php/$2 [NC,L]

    thanks for you time.

    1. Hi Mark, my first guess here should be this is a javascript issue. The hash is often used by js to represent some sort of state of the client. Do you use a js script which does some specific (workaround) tricks for IE?

      Also try to find someone who can help you side by side if you’re not a programmer. Will save you some headaches ;).

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *