How do I fix a wrong 301 redirect from http to https on Wordpress website?

69 views Asked by At

I got a Wordpress website, lets call it example.com, hosted by IONOS. It is a https site with a working SQL certificate, so all http requests should redirect to the requested page but replace the http with https.

Example: http://example.com should redirect to https://example.com (this works) http://example.com/subpage should redirect to https://example.com/subpage (it doesn't do this though!) What it does instead is: http://example.com/subpage redirects to https://example.com/

The main issue with this is Google Search Console wrongly detecting a redirect error for every subpage it tries to index, though the index request i sent was specifically for the https site (https://example.com/subpage).

I am running on the latest version of Wordpress. The plugins I currently have installed are:

Advanced Import
Duplicate Page
Elementor Pro
IONOS Assistant (deactivated)
IONOS Help (deactivated)
IONOS Journey (deactivated)
IONOS Login
IONOS Loop (deactivated)
IONOS Navigation
IONOS Performance
IONOS Security
Music Player for Elementor
Title Remover
WPvivid Backup Plugin
Yoast SEO Premium

This is my .htaccess file:

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/cache-manifest
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/vcard
    AddOutputFilterByType DEFLATE text/vnd.rim.location.xloc
    AddOutputFilterByType DEFLATE text/vtt
    AddOutputFilterByType DEFLATE text/x-component
    AddOutputFilterByType DEFLATE text/x-cross-domain-policy
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/ld+json
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE application/manifest+json
    AddOutputFilterByType DEFLATE application/rdf+xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/schema+json
    AddOutputFilterByType DEFLATE application/vnd.geo+json
    AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
    AddOutputFilterByType DEFLATE application/x-font-ttf
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/x-web-app-manifest+json
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE font/eot
    AddOutputFilterByType DEFLATE font/opentype
    AddOutputFilterByType DEFLATE image/bmp
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE image/vnd.microsoft.icon
    AddOutputFilterByType DEFLATE image/x-icon
</IfModule>
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css A2419200
    ExpiresByType text/x-component A2419200
    ExpiresByType application/x-javascript A2419200
    ExpiresByType application/javascript A2419200
    ExpiresByType text/javascript A2419200
    ExpiresByType text/x-js A2419200
    ExpiresByType text/html A3600
    ExpiresByType text/richtext A3600
    ExpiresByType image/svg+xml A3600
    ExpiresByType text/plain A3600
    ExpiresByType text/xsd A3600
    ExpiresByType text/xsl A3600
    ExpiresByType text/xml A3600
    ExpiresByType video/asf A2419200
    ExpiresByType video/avi A2419200
    ExpiresByType image/bmp A2419200
    ExpiresByType application/java A2419200
    ExpiresByType video/divx A2419200
    ExpiresByType application/msword A2419200
    ExpiresByType application/vnd.ms-fontobject A2419200
    ExpiresByType application/x-msdownload A2419200
    ExpiresByType image/gif A2419200
    ExpiresByType application/x-gzip A2419200
    ExpiresByType image/x-icon A2419200
    ExpiresByType image/jpeg A2419200
    ExpiresByType application/json A2419200
    ExpiresByType application/vnd.ms-access A2419200
    ExpiresByType audio/midi A2419200
    ExpiresByType video/quicktime A2419200
    ExpiresByType audio/mpeg A2419200
    ExpiresByType video/mp4 A2419200
    ExpiresByType video/mpeg A2419200
    ExpiresByType application/vnd.ms-project A2419200
    ExpiresByType application/x-font-otf A2419200
    ExpiresByType application/vnd.ms-opentype A2419200
    ExpiresByType application/vnd.oasis.opendocument.database A2419200
    ExpiresByType application/vnd.oasis.opendocument.chart A2419200
    ExpiresByType application/vnd.oasis.opendocument.formula A2419200
    ExpiresByType application/vnd.oasis.opendocument.graphics A2419200
    ExpiresByType application/vnd.oasis.opendocument.presentation A2419200
    ExpiresByType application/vnd.oasis.opendocument.spreadsheet A2419200
    ExpiresByType application/vnd.oasis.opendocument.text A2419200
    ExpiresByType audio/ogg A2419200
    ExpiresByType application/pdf A2419200
    ExpiresByType image/png A2419200
    ExpiresByType application/vnd.ms-powerpoint A2419200
    ExpiresByType audio/x-realaudio A2419200
    ExpiresByType image/svg+xml A2419200
    ExpiresByType application/x-shockwave-flash A2419200
    ExpiresByType application/x-tar A2419200
    ExpiresByType image/tiff A2419200
    ExpiresByType application/x-font-ttf A2419200
    ExpiresByType application/vnd.ms-opentype A2419200
    ExpiresByType audio/wav A2419200
    ExpiresByType audio/wma A2419200
    ExpiresByType application/vnd.ms-write A2419200
    ExpiresByType application/font-woff A2419200
    ExpiresByType application/vnd.ms-excel A2419200
    ExpiresByType application/zip A2419200
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{SERVER_PORT} 80
    RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

# Block the include-only files.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
<Files wp-config.php>
order allow,deny
deny from all
</Files>

# START IONOS Performance Caching
# IONOS Caching Snippet v2
<IfModule mod_setenvif.c>
    SetEnvIf REQUEST_METHOD "^(?!GET).*$" INITIAL_REQUEST_METHOD=NOGET
</IfModule>

<IfModule mod_rewrite.c>
    # ENGINE ON
    RewriteEngine on

    # set hostname directory
    RewriteCond %{HTTPS} on
    RewriteRule .* - [E=IONOS_PERFORMANCE_HOST:https-%{HTTP_HOST}]

    RewriteCond %{HTTPS} off
    RewriteRule .* - [E=IONOS_PERFORMANCE_HOST:%{HTTP_HOST}]

    # set subdirectory
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_METHOD} GET
    RewriteCond %{REQUEST_URI} !(.*)/$
    RewriteCond %{REQUEST_FILENAME} !.(gif|jpg|png|jpeg|css|xml|txt|js|php|scss|webp|mp3|avi|wav|mp4|mov)$ [NC]
    RewriteRule .* - [E=IONOS_PERFORMANCE_DIR:%{REQUEST_URI}/]

    RewriteCond %{REQUEST_URI} /$
    RewriteRule .* - [E=IONOS_PERFORMANCE_DIR:%{REQUEST_URI}]

    RewriteCond %{REQUEST_URI} ^$
    RewriteRule .* - [E=IONOS_PERFORMANCE_DIR:/]

    # gzip
    RewriteRule .* - [E=IONOS_PERFORMANCE_SUFFIX:]
    <IfModule mod_mime.c>
        RewriteCond %{HTTP:Accept-Encoding} gzip
        RewriteRule .* - [E=IONOS_PERFORMANCE_SUFFIX:.gz]
        AddType text/html .gz
        AddEncoding gzip .gz
    </IfModule>

    # Main Rules
    RewriteCond %{HTTP_ACCEPT} .*text/html.*
    RewriteCond %{ENV:INITIAL_REQUEST_METHOD} ^$
    RewriteCond %{ENV:REDIRECT_INITIAL_REQUEST_METHOD} ^$
    RewriteCond %{QUERY_STRING} ^$
    RewriteCond %{REQUEST_URI} !^/(wp-admin|wp-content/cache)/.*
    RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
    RewriteCond /homepages/9/d4297862886/htdocs/./wordpress/wp-content/cache/ionos-performance/%{ENV:IONOS_PERFORMANCE_HOST}%{ENV:IONOS_PERFORMANCE_DIR}index.html%{ENV:IONOS_PERFORMANCE_SUFFIX} -f
    RewriteRule ^(.*) /wp-content/cache/ionos-performance/%{ENV:IONOS_PERFORMANCE_HOST}%{ENV:IONOS_PERFORMANCE_DIR}index.html%{ENV:IONOS_PERFORMANCE_SUFFIX} [L]
</IfModule>
# END IONOS Performance Caching

# BEGIN WordPress
# Die Anweisungen (Zeilen) zwischen „BEGIN WordPress“ und „END WordPress“ sind
# dynamisch generiert und sollten nur über WordPress-Filter geändert werden.
# Alle Änderungen an den Anweisungen zwischen diesen Markierungen werden überschrieben.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

These are the snippets of the .htaccess file that might be responsible from what I can see (I am not an expert in web development):

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{SERVER_PORT} 80
    RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

and:

<IfModule mod_rewrite.c>
    # ENGINE ON
    RewriteEngine on

    # set hostname directory
    RewriteCond %{HTTPS} on
    RewriteRule .* - [E=IONOS_PERFORMANCE_HOST:https-%{HTTP_HOST}]

    RewriteCond %{HTTPS} off
    RewriteRule .* - [E=IONOS_PERFORMANCE_HOST:%{HTTP_HOST}]

    # set subdirectory
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_METHOD} GET
    RewriteCond %{REQUEST_URI} !(.*)/$
    RewriteCond %{REQUEST_FILENAME} !.(gif|jpg|png|jpeg|css|xml|txt|js|php|scss|webp|mp3|avi|wav|mp4|mov)$ [NC]
    RewriteRule .* - [E=IONOS_PERFORMANCE_DIR:%{REQUEST_URI}/]

    RewriteCond %{REQUEST_URI} /$
    RewriteRule .* - [E=IONOS_PERFORMANCE_DIR:%{REQUEST_URI}]

    RewriteCond %{REQUEST_URI} ^$
    RewriteRule .* - [E=IONOS_PERFORMANCE_DIR:/]

    # gzip
    RewriteRule .* - [E=IONOS_PERFORMANCE_SUFFIX:]
    <IfModule mod_mime.c>
        RewriteCond %{HTTP:Accept-Encoding} gzip
        RewriteRule .* - [E=IONOS_PERFORMANCE_SUFFIX:.gz]
        AddType text/html .gz
        AddEncoding gzip .gz
    </IfModule>

    # Main Rules
    RewriteCond %{HTTP_ACCEPT} .*text/html.*
    RewriteCond %{ENV:INITIAL_REQUEST_METHOD} ^$
    RewriteCond %{ENV:REDIRECT_INITIAL_REQUEST_METHOD} ^$
    RewriteCond %{QUERY_STRING} ^$
    RewriteCond %{REQUEST_URI} !^/(wp-admin|wp-content/cache)/.*
    RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
    RewriteCond /homepages/9/d4297862886/htdocs/./wordpress/wp-content/cache/ionos-performance/%{ENV:IONOS_PERFORMANCE_HOST}%{ENV:IONOS_PERFORMANCE_DIR}index.html%{ENV:IONOS_PERFORMANCE_SUFFIX} -f
    RewriteRule ^(.*) /wp-content/cache/ionos-performance/%{ENV:IONOS_PERFORMANCE_HOST}%{ENV:IONOS_PERFORMANCE_DIR}index.html%{ENV:IONOS_PERFORMANCE_SUFFIX} [L]
</IfModule>

and at last:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

My Wordpress Permalink setting is set up this way:

https://example.com/%category/%postname%/

What could be a possible fix for this? If you need any more information feel free to ask for it.

1

There are 1 answers

2
arkascha On

My spontaneous impression is that the following redirection is the culprit:

RewriteRule ^(/(.*))?$ https://%{HTTP_HOST}/$1 [R=301,L]

You need to keep in mind that a RewriteRule that is implemented in a distributed configuration file (often called ".htaccess") behaves slightly different to one implemented in the actual, central configuration of the http server and its hosts.

When implemented in a distributed file the rule matches on the relative path that has been requested. That is clearly documented behavior! Such a relative path will never start with a trailing slash, that does not make any sense. Which is why the pattern ^(/(.*))?$ will never match anything but the empty path, so only if http://example.com/ has been requested.

I assume that some other feature of the environment you are using is responsible for the actual redirection to https, something not implemented by your rewriting rules. But by some framework settings or even the central host configuration inside that http server.


The easiest way to fix this probably is to simply change the existing implementation to that variant:

RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

The pattern ^ matches anything and the variable %{REQUEST_URI} contains the absolute requested path, so a path with a leading slash.