HTTPS redirect not working on a specific endpoint

I am using the following in my .htaccess file to force HTTPS

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]

This works perfectly for all pages except one page - /workbook

When visiting you are redirected to /index.php rather than added the correct https prefix like it does on all other pages.

This only happens when http and no www are used. If http and www are used together it does works. No other page on the website is behaving like this, just /workbook.

Additionally if a change the URL to something else ie /workbooktest it redirects correctly, but changing the URL isn’t possible as it’s linked in a physical book.

What could be different about this particularly URL that Kirby doesn’t like?

If I enter that URL in my browser, it correctly redirects to https://www./ Maybe some browser caching on your side?

I have a very similar problem. Here’s my example:


redirects to index.php


redirects to

This next part seems like it could be related, but is also a little different:

In Chrome 

redirects to

adding www correctly, but in FireFox I’m seeing the error code SSL_ERROR_BAD_CERT_DOMAIN because the cert is for www only.

The cert is through Let’s Encrypt.

My .htaccess looks like this:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.andybeckmann\.com$ [NC]
RewriteRule ^(.*)$$1 [L,R=301]

You might want to check this out:

I looked through that link and tried a few of the suggestions but nothing was working.

I decided to do a test by adding a folder with a generic index.html to my site root, and my htaccess code works as expected. This leads me to believe this is an issue with Kirby losing the URI.

Regular folder:

redirects to:

as expected.

Kirby page:

redirects to:

So I am back to my original code and wondering if I’m doing something Kirby can’t handle, as it seems to work as intended:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.andybeckmann\.com$ [NC]
RewriteRule ^(.*)$$1 [L,R=301]

Could you please post the complete .htaccess file? Also, what’s going on in custom routes (config/plugins)?


# Kirby .htaccess    

# rewrite rules
<IfModule mod_rewrite.c>    

# enable awesome urls. i.e.:
RewriteEngine on    

# make sure to set the RewriteBase correctly
# if you are running the site in a subfolder.
# Otherwise links or the entire site will break.
# If your homepage is
# Set the RewriteBase to:
# RewriteBase /mysite    

# In some environments it's necessary to
# set the RewriteBase to:
RewriteBase /    

# block files and folders beginning with a dot, such as .git
# except for the .well-known folder, which is used for Let's Encrypt and security.txt
RewriteRule (^|/)\.(?!well-known\/) index.php [L]    

# block text files in the content folder from being accessed directly
RewriteRule ^content/(.*)\.(txt|md|mdown)$ index.php [L]    

# block all files in the site folder from being accessed directly
# except for requests to plugin assets files
RewriteRule ^site/(.*) index.php [L]    

# Enable authentication header
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1    

# block direct access to kirby and the panel sources
RewriteRule ^kirby/(.*) index.php [L]    

# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]    


# compress text file responses
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript

# Force SSL and WWW
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.andybeckmann\.com$ [NC]
RewriteRule ^(.*)$$1 [L,R=301]    

# Rewrite old page URLs
# Redirect 301 /old
Redirect 301 /portfolio
Redirect 301 /about
Redirect 301 /privacy
Redirect 301 /suggestions
Redirect 301 /blog/2016/04/05/hello-world
Redirect 301 /blog/2016/04/06/fixing-issues-with-handbrake-in-mac-os
Redirect 301 /blog/2016/04/28/exporting-images-from-adobe-photoshop
Redirect 301 /blog/2016/05/05/fix-path-issues-on-localhost-with-php
Redirect 301 /blog/2016/05/22/thoughts-on-future-of-tcp
Redirect 301 /blog/2016/05/30/thoughts-on-decentralized-tech
Redirect 301 /blog/2016/06/26/12-million-ether-has-been-stolen
Redirect 301 /blog/2016/07/09/hacker-wars-kypertech-vs-hashocean
Redirect 301 /blog/2016/07/11/new-ethos-background-designs
Redirect 301 /blog/2016/07/20/ethereum-successfully-implements-hardfork
Redirect 301 /blog/2016/07/20/update-on-kypertech



return [

    'debug' => false,

    'routes' => [
	    'pattern' => 'sitemap.xml',
	    'action'  => function() {
	        $pages = site()->pages()->index();

	        // fetch the pages to ignore from the config settings,
	        // if nothing is set, we ignore the error page
	        $ignore = kirby()->option('sitemap.ignore', ['error']);

	        $content = snippet('sitemap', compact('pages', 'ignore'), true);

	        // return response with correct header type
	        return new Kirby\Cms\Response($content, 'application/xml');
	    'pattern' => 'sitemap',
	    'action'  => function() {
	      return go('sitemap.xml', 301);
	'sitemap.ignore' => ['error'],



Kirby::plugin('starterkit/gallery', [
    'hooks' => [
        'kirbytags:after' => function ($text, $data, $options) {

            if ($page = $data['parent']->gallery()->toPage()) {
                $gallery = snippet('gallery', ['gallery' => $page], true);
            } else {
                $gallery = '';

            return str_replace('{{ gallery }}', $gallery, $text);

I think that plugin is leftover from the starter build.