Having issues with redirects and training slashes


My site “disapeared” a month or so back, but after I implemented my backup I started getting errors. The htaccess didnt survive the backup and I had to reconstruct it all over again.

I have a 301 to direct to the non-www version of the site… but in google webmaster tools I get notices like this.


it should be redirected to

But its not… the top link just sends me to my 404 page.

Can anyone tell me what Im doing wrong?

Thank you in advance.


Certainly: Your .htaccess is either not being read or its “301” is incorrect. You’ll actually have to show your code for us to have a better chance to help, though.



Oh sorry, I apologize.

I got my htaccess file from the html5 boilerplate and adjusted it as needed.

 <IfModule mod_headers.c>
  Header set X-UA-Compatible "IE=Edge,chrome=1"
  # mod_headers can't match by content-type, but we don't want to send this header on *everything*...
  <FilesMatch "\\.(js|css|gif|png|jpe?g|pdf|xml|oga|ogg|m4a|ogv|mp4|m4v|webm|svg|svgz|eot|ttf|otf|woff|ico|webp|appcache|manifest|htc|crx|oex|xpi|safariextz|vcf)$" >
    Header unset X-UA-Compatible

<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    # mod_headers, y u no match by Content-Type?!
    <FilesMatch "\\.(gif|png|jpe?g|svg|svgz|ico|webp)$">
      SetEnvIf Origin ":" IS_CORS
      Header set Access-Control-Allow-Origin "*" env=IS_CORS

<IfModule mod_headers.c>
  <FilesMatch "\\.(ttf|ttc|otf|eot|woff|font.css)$">
    Header set Access-Control-Allow-Origin "*"

# ----------------------------------------------------------------------
# Proper MIME type for all files
# ----------------------------------------------------------------------

# JavaScript
#   Normalize to standard type (it's sniffed in IE anyways)
#   tools.ietf.org/html/rfc4329#section-7.2
AddType application/javascript         js jsonp
AddType application/json               json

# Audio
AddType audio/ogg                      oga ogg
AddType audio/mp4                      m4a f4a f4b

# Video
AddType video/ogg                      ogv
AddType video/mp4                      mp4 m4v f4v f4p
AddType video/webm                     webm
AddType video/x-flv                    flv

#   Required for svg webfonts on iPad
#   twitter.com/FontSquirrel/status/14855840545
AddType     image/svg+xml              svg svgz
AddEncoding gzip                       svgz

# Webfonts
AddType application/vnd.ms-fontobject  eot
AddType application/x-font-ttf         ttf ttc
AddType font/opentype                  otf
AddType application/x-font-woff        woff

# Assorted types
AddType image/x-icon                        ico
AddType image/webp                          webp
AddType text/cache-manifest                 appcache manifest
AddType text/x-component                    htc
AddType application/xml                     rss atom xml rdf
AddType application/x-chrome-extension      crx
AddType application/x-opera-extension       oex
AddType application/x-xpinstall             xpi
AddType application/octet-stream            safariextz
AddType application/x-web-app-manifest+json webapp
AddType text/x-vcard                        vcf
AddType application/x-shockwave-flash       swf
AddType text/vtt                            vtt

# ----------------------------------------------------------------------
# Gzip compression
# ----------------------------------------------------------------------

<IfModule mod_deflate.c>

  # Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/
  <IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
      SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\\s*,?\\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
      RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding

  # Compress all output labeled with one of the following MIME-types
  <IfModule mod_filter.c>
    AddOutputFilterByType DEFLATE application/atom+xml \\
                                  application/javascript \\
                                  application/json \\
                                  application/rss+xml \\
                                  application/vnd.ms-fontobject \\
                                  application/x-font-ttf \\
                                  application/xhtml+xml \\
                                  application/xml \\
                                  font/opentype \\
                                  image/svg+xml \\
                                  image/x-icon \\
                                  text/css \\
                                  text/html \\
                                  text/plain \\
                                  text/x-component \\


# ----------------------------------------------------------------------
# Expires headers (for better cache control)
# ----------------------------------------------------------------------

<IfModule mod_expires.c>
  ExpiresActive on

# Perhaps better to whitelist expires rules? Perhaps.
  ExpiresDefault                          "access plus 1 month"

# cache.appcache needs re-requests in FF 3.6 (thanks Remy ~Introducing HTML5)
  ExpiresByType text/cache-manifest       "access plus 0 seconds"

# Your document html
  ExpiresByType text/html                 "access plus 0 seconds"

# Data
  ExpiresByType text/xml                  "access plus 0 seconds"
  ExpiresByType application/xml           "access plus 0 seconds"
  ExpiresByType application/json          "access plus 0 seconds"

# Feed
  ExpiresByType application/rss+xml       "access plus 1 hour"
  ExpiresByType application/atom+xml      "access plus 1 hour"

# Favicon (cannot be renamed)
  ExpiresByType image/x-icon              "access plus 1 week"

# Media: images, video, audio
  ExpiresByType image/gif                 "access plus 1 week"
  ExpiresByType image/png                 "access plus 1 week"
  ExpiresByType image/jpeg                "access plus 1 week"
  ExpiresByType video/ogg                 "access plus 1 week"
  ExpiresByType audio/ogg                "access plus 1 week"
  ExpiresByType video/mp4                 "access plus 1 week"
  ExpiresByType video/webm                "access plus 1 week"

# HTC files  (css3pie)
  ExpiresByType text/x-component          "access plus 1 month"

# Webfonts
  ExpiresByType application/x-font-ttf    "access plus 1 month"
  ExpiresByType font/opentype             "access plus 1 month"
  ExpiresByType application/x-font-woff   "access plus 1 month"
  ExpiresByType image/svg+xml             "access plus 1 month"
  ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

# CSS and JavaScript
  ExpiresByType text/css                  "access plus 1 week"
  ExpiresByType application/javascript    "access plus 1 week"


# ----------------------------------------------------------------------
# ETag removal
# ----------------------------------------------------------------------

# FileETag None is not enough for every server.
<IfModule mod_headers.c>
  Header unset ETag

FileETag None

# ----------------------------------------------------------------------
# Start rewrite engine
# ----------------------------------------------------------------------

<IfModule mod_rewrite.c>
  Options +FollowSymlinks
# Options +SymLinksIfOwnerMatch
  RewriteEngine On
# RewriteBase /

# ----------------------------------------------------------------------
# Suppress or force the "www." at the beginning of URLs
# ----------------------------------------------------------------------
# Option 1:
# Rewrite "www.example.com -> example.com".

<IfModule mod_rewrite.c>
  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP_HOST} ^www\\.(.+)$ [NC]
  RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

# ----------------------------------------------------------------------

# Option 2:
# Rewrite "example.com -> www.example.com".
# Be aware that the following rule might not be a good idea if you use "real"
# subdomains for certain parts of your website.

# <IfModule mod_rewrite.c>
#   RewriteCond %{HTTPS} !=on
#   RewriteCond %{HTTP_HOST} !^www\\..+$ [NC]
#   RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# </IfModule>

# ----------------------------------------------------------------------
# Custom 404 page
# ----------------------------------------------------------------------

ErrorDocument 404 /404.html

# ----------------------------------------------------------------------
# UTF-8 encoding
# ----------------------------------------------------------------------

AddDefaultCharset utf-8

# Force UTF-8 for a number of file formats
AddCharset utf-8 .atom .css .js .json .rss .vtt .xml

# ----------------------------------------------------------------------
# A little more security
# ----------------------------------------------------------------------

<IfModule mod_autoindex.c>
  Options -Indexes

<IfModule mod_rewrite.c>
  RewriteCond %{SCRIPT_FILENAME} -d [OR]
  RewriteCond %{SCRIPT_FILENAME} -f
  RewriteRule "(^|/)\\." - [F]

<FilesMatch "(\\.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$">
  Order allow,deny
  Deny from all
  Satisfy All

# Increase cookie security
<IfModule php5_module>
  php_value session.cookie_httponly true

RewriteCond %{REQUEST_URI} !(/$|\\.) 
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L] 

You can see where at the end I tried to add the trailing slash to see if that fixed things… but it didnt (obviously).

Thanks for any help you can give.


No problem … except with the absurd .htaccess file you’re employing!

First, realize that EVERY .htaccess file in the path must be read, parsed and executed (if needed) for EVERY file request. Having such a long .htaccess means that you’re wasting an immense amount of time/CPU cycles to access EVERY file. To make matters worse, you’re also making MULTIPLE <IfModule> tests every time, too. This is so bad that I’ve got a Standard Rant just for that:

[rant #4][indent]The definition of an idiot is someone who repeatedly does the same thing expecting a different result. Asking Apache to confirm the existence of ANY module with an <IfModule> … </IfModule> wrapper is the same thing in the webmaster world. DON’T BE AN IDIOT! If you don’t know whether a module is enabled, run the test ONCE then REMOVE the wrapper as it is EXTREMELY wasteful of Apache’s resources (and should NEVER be allowed on a shared server).[/indent][/rant 4]

As for your mod_rewrite code, please use the code wrapper (so it’s included in a quoted reply):

RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

“If not secure server and www subdomain requested, strip www.” Okay, successful, but I’d drop the ^(null) and simply use .? to ensure a true regex.

RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\\." - [F]

“If a directory or file and containing a dot character, Fail.” What’s that about?

RewriteCond %{REQUEST_URI} !(/$|\\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L] 

“If not a trailing / or containing a dot character (???), add a trailing /.” WHY? IMHO, trailing / is unforgiveable (unless it’s a directory) because it changes the directory level for relative links within the served file.



lol… I think its hilarious you have standardized rants that you keep handy.

Im not a web developer, I just wanted to make a little site to help out Sailors and others. The reason I tried the trailing slash because I was wondering why the link in the original post was going to the 404 page instead of the non-www page and the only difference I saw in the url was the trailing slash… so I thought maybe that was the problem… seems I was wrong.

As far as the absurd htaccess file, I simply used the file that came with the html 5 boilerplate and went from there. Obviously, they are smarter than I so I left it up to them.

With that out of the way, I tried to implement the code you gave me and my problem still exists.

Seems I have a lot of learning to do with this htaccess stuff.


Well, I was a Moderator and Team Leader here for a LOoooonnnNGGG time so I had to do that because I was answering the same questions over and over … FWIW, I use AutoHotKey and merely type in a code for a piece of text, ergo, my standard rants are easy - if I can remember which number goes with which problem area! :smiley:

IMHO, wildly using trailing slashes is extremely bad - and it’ll bite your behind if you’re not really careful! My recommendation is to use /'s as they’re intended, i.e., to denote directories.

The boilerplate you used was, well, absurd. My Standard Rant #4 was generated because WordPress started using the <IfModule> wrapper to avoid being plagued by complaints that the .htaccess they installed crippled websites (which didn’t have mod_rewrite installed). Too bad they didn’t add a WARNING statement to say how abusive it is on a server. Your boilerplate, however, went overboard in a big way and the creators should be excluded from every shared server (including VPS’s) for their stupidity.

Sorry, the code I gave you was merely parroting back your code and commenting on the “errors” therein. It was left to you as an exercise to clean it up. I learned long ago not to code for “script kiddies” so I really limit my corrections to comments the first time around. When you update your code, I’ll be happy to help you to make it work.

In case I hadn’t recommended it before, you might benefit from reading the mod_rewrite tutorial linked in my signature as it contains explanations and sample code. It’s helped may members and should help you, too (yes, another AutoHotKey entry albeit not a rant).