Front-end logging out not working

I have set up basic user registration/login/log out functionality (without panel access) for this site:

I am however having issues with the logging out via the front-end.

In my template I have :

<?php if ($user = $kirby->user()): ?>
<a href="<?= url('logout') ?>">Log out</a>
<?php endif ?>

And in my config.php :

'routes' => [
        'pattern' => 'logout',
        'action'  => function() {

          if ($user = kirby()->user()) {



Locally it works fine.

When I check on a live server however, the first time I log out it works correctly. But if I log back in and log out again, it does not work. When clicking the “log out” button I am routed to the home page and I remain logged in.

Does anybody have an idea of which angle I could start debugging this from?

thank you

Is that your only route?

Yes that’s my only route.

Have you checked what exactly happens in the network tab?

In the network tab I can see that there are some redirects happening:

logout Redirect →
login Redirect →

It’s as if it hits the logout route/login page thinking the user is still logged in, which redirects to home.

Seems like it could be a cache-ing problem because if I disable cache in dev tools, the problem disappears …(?)

I wonder if this issue on GitHub is related: Session: Disable cache on active sessions · Issue #3242 · getkirby/kirby · GitHub

Ping @lukasbestle?

I don‘t think so. Routes are currently not cached and it doesn‘t explain why clearing the browser cache solves it.

@kiahr Could you please check the following:

  1. Clear your browser cache again.
  2. Open devtools and click that logout button.
  3. Check what HTTP status code gets returned for the /login redirect. 301 or 302?

Hey @lukasbestle, it is a 302.

That seems right. So I think you are indeed logged out, but you get a cached representation of the page.

Please try sending a Cache-Control: private, no-cache header when a user is logged in:

header('Cache-Control: private, no-cache');

This should prevent your browser from using the cached response from the first visit. If that solves it, we will fix it in the upcoming Kirby release. Please let me know. :slightly_smiling_face:

Hi @lukasbestle,

I tried adding the header in the login.php controller after the authentication and before the go(), however the issue still remains. Would that be the best place for it?


return function ($kirby) {

  if ($kirby->user()) {

  $error = false;

  if ($kirby->request()->is('POST') && get('login')) {

    try {

      $kirby->auth()->login(get('email'), get('password'));
      header('Cache-Control: private, no-cache');

    } catch (Exception $e) {

      $error = true;

  return [
    'error' => $error


I have tried across browsers, and also updated to the latest version of Kirby, but this has not fixed it either.

Extra note
On Safari it works slightly differently, if I log in then log out and navigate to other pages that have if statements such as (if logged in show this), it believes I am still logged in and shows the content for a logged in user. :grimacing:

You will need the header on each page that contains user-specific information, not just on the login page itself. For testing you can put it into the templates of the affected pages inside the “if logged in show this” blocks.

After you made the change, make sure to clear the browser cache again before testing.

As I wrote, we will fix this in the upcoming release, so you only need this change temporarily.

Hey @lukasbestle, thanks for that info and the support.

I added the header() to all pages within an “if logged in” block, cleared the browser cache and tested it again.

Even though I can see in dev tools the “cache-control :private, no-cache” under the Response Headers, it is still having a lot of issues. After that second Log in and Log out, the header is being added on some pages, but not on others and the issues still remains with the:

logout redirects to → login which redirects to → home

Do you have Kirby’s page cache enabled? If so, please disable it for testing and clear the site/cache directory.

I have disabled Kirby’s cache via the config:

'cache' => [
    'pages' => [
        'active' => false

And deleted the contents of the site/cache folder, however the issue remains.

Perhaps I will test it on a fresh starter kit install tomorrow. If the problem is still there, I hope you don’t mind me writing you again.

Hm, now I‘m out of ideas. Testing with the Starterkit is a good idea! Feel free to get in touch if the issue persists.

Running into this same issue.

I have a site where some pages are password protected. The password protected pages are setup to redirect to a login page if !$kirby->user(). The email address is hard coded into the login controller, so users just need a password.

In the front end nav there is a link that shows a log out button, only for logged in users

<?php if($kirby->user()): ?>
  <li><a href="<?= $site->url() ?>/logout" noprefetch >Logout</a></li>
<?php endif ?>

in my config i have a route to log out the user that looks like this:

  'pattern' => 'logout',
  'action'  => function() {
    if ($user = kirby()->user()) {

This logout link seems to work erratically, sometimes it will work, then i log in again and it will not work. i will get redirected to the /success page, but the logout link will still be visible in the nav, meaning im still logged in.

I don’t have any caching turned on. any ideas what might cause this?

  • opening dev tools and disabling the cache does seem to fix this.
  • changing the logout url to /logout?1 or /logout?2 seems to fix this. But each url just works once, like the browser is somehow caching it.

What if you call kirby()->auth()->logout() instead of $user->logout()?

still not working with kirby()->auth()->logout()

here is a demo: (removed)

the logout link will work once, but after logging in again, it stops working but still redirects to the success page.

here is the route being used for testing:

  'pattern' => 'logout',
  'action'  => function() {
    if ($user = kirby()->user()) {
      // $user->logout();
  • the server (Dreamhost) is running PHP 8.1 FastCGI
  • I can’t replicate the issue on my local env

Looks like the user is not removed from the session, if you look at the session value, it doesn’t change on logout like it should. What I can’t tell why. Maybe Dreamhost has some caching enabled?

Ping @lukasbestle

changing from php 8.1 to 8.0 seems to have fixed this!