.htaccess redirects no longer work

RedirectMatch 301 ^/watermeloncakes/ //www.clienturl.com/watermelon-cakes-1/

(I assuming www.clienturl.com is the hostname for this site.)

Well, here’s the thing… this would never have worked on any version of Apache!? Because protocol-relative URLs are not supported by mod_alias RedirectMatch (or Redirect) or mod_rewrite for that matter.

From the Apache docs:

The new URL may be either an absolute URL beginning with a scheme and hostname, or a URL-path beginning with a slash. In this latter case the scheme and hostname of the current server will be added.

A protocol-relative URL such as //www.clienturl.com/watermelon-cakes-1/ will simply be seen as root-relative (“a URL-path beginning with a slash”), so the above directive would result in a malformed redirect to:

https://www.clienturl.com//www.clienturl.com/watermelon-cakes-1/

It’s possible that another redirect later corrected this (perhaps in WordPress itself)!? But there is no evidence of this in your .htaccess file.

It is Apache that constructs this absolute URL when it creates the Location header to send back to the client. It doesn’t send back a protocol-relative URL and expect the client to resolve it (which you could do if you manually assigned a value to the Location header in your server-side script).

If these directives ever worked, then it looks like someone has either removed the protocol (https: or http:?) from the target URL, or added the hostname (//www.clienturl.com)? Is it possible that these were initially redirects to http: and someone thought they’d try to avoid the “double redirect” (since you are forcing HTTPS) by making them “protocol relative”?

The above directive would need to either use a full absolute URL:

RedirectMatch 301 ^/watermeloncakes/ https://www.clienturl.com/watermelon-cakes-1/

Or use a root-relative URL:

RedirectMatch 301 ^/watermeloncakes/ /watermelon-cakes-1/

Use mod_rewrite instead

However, you should really be using mod_rewrite RewriteRule for these redirects instead of a mod_alias RedirectMatch (or Redirect) directive. Simply because you should avoid mixing redirects/rewrites from both modules and you are already using mod_rewrite throughout your .htaccess file – WordPress itself uses mod_rewrite to implement its front-controller model.

For example:

RewriteRule ^watermeloncakes/ /watermelon-cakes-1/ [R=301,L]

(There is no need to repeat the RewriteEngine directive.)

Apache modules execute independently and at different times throughout the request. mod_rewrite executes before mod_alias, regardless of the apparent order of the directives in the .htaccess file. You could, for instance, place all the RedirectMatch directives at the end of the file and it would make no difference to the execution order.

So, by mixing redirects from both modules you can end up with unexpected conflicts, since mod_rewrite will always take priority, regardless of the order. But also, all the mod_rewrite directives are being processed first, before the mod_alias redirects – everything is being processed on every request (regardless of whether there is a redirect or not). If you use mod_rewrite then the redirect occurs immediately and the remaining directives are bypassed.

Use WordPress instead (preferable)

However, since all these redirects look as if they are probably just correcting URLs, URLs that would otherwise trigger 404s then it would be preferable to perform these redirects in your server-side code (ie. WordPress) instead. For example, once WordPress has determined the URL would result in a 404, then check your redirects. Doing it this way avoids any of the redirect code “slowing down” normal site usage.