# Dashboard 2.0 PWA: Service Worker prevents authentication redirect when session expires

**URL:** https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574
**Category:** Dashboard
**Tags:** dashboard-2
**Created:** [16 March 2026 07:14 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574 "2026-03-16T07:14:09Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [16 March 2026 07:14 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/1 "2026-03-16T07:14:09Z")

</div>

I'm running Node-RED with Dashboard 2.0 behind Cloudflare Access (Zero Trust), which handles authentication. The dashboard is accessed via a public URL that tunnels back to my home network. I've installed the dashboard as a PWA on my iPhone (Add to Home Screen), so it opens in its own standalone window.

The Cloudflare Access session expires after a set amount of time. When this happens and I open the PWA, I expect to be redirected to the Cloudflare login page so I can re-authenticate. Instead, I see "There was an error loading the Dashboard" with the disconnected image and a "Reload App" button. Reloading does not help, it shows the same error every time.  
The only way I've found to recover is to delete the PWA from my home screen and re-add it.  
What's happening under the hood:  
I captured HAR files from the failing sessions and the root cause seems to be that the Service Worker that Dashboard 2.0 registers caches everything, including index.html and the main JS bundle. When I open the PWA:

1. The Service Worker intercepts the navigation request and serves index.html from its cache (status 200, \_fetchType: "Service Worker")
2. The cached JavaScript boots the Vue app and calls fetch("\_setup")
3. The \_setup request goes to the network, but Cloudflare Access blocks it (session expired) and the cross-origin redirect causes the fetch to fail
4. The catch handler shows "There was an error loading the Dashboard"
5. No request ever reaches the network, so Cloudflare never gets a chance to redirect to its login page

Has anyone else run into this? Is there a configuration option I'm missing, or would this need a change in how the dashboard's Service Worker is configured?

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [16 March 2026 09:29 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/2 "2026-03-16T09:29:33Z")

</div>

Hi,

We've seen similar issues with the service worker and I have spent hours trying to figure out how to fix it. In the end, the only reliable fix I could find was to disable the service worker entirely (which you can do in the dashboard base config node).

The problem comes down to the service working making http requests to revalidate its manifest - and those requests failing auth. I could not find anyway to programmatically react to those failing requests.This must be a common problem with service workers, but I couldn't find any useful tips on how to resolve it.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [16 March 2026 10:07 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/3 "2026-03-16T10:07:08Z")

</div>

On Android, refreshing the page sends it to the login page.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [16 March 2026 10:20 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/4 "2026-03-16T10:20:04Z")

</div>

Oh, sorry, I see that I have disabled Install as App.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [16 March 2026 11:08 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/5 "2026-03-16T11:08:24Z")

</div>

> [@knolleary](#):
>
> I could not find anyway to programmatically react to those failing requests.

Something must receive the 301 redirect - is that in Node-RED or in the web worker?

Surely there must be a way to detect getting a 301 instead of a valid response?

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [16 March 2026 11:12 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/6 "2026-03-16T11:12:00Z")

</div>

> [@TotallyInformation](#):
>
> Surely there must be a way to detect getting a 301 instead of a valid response?

That is what I assume, and what I have spent a lot of time trying to figure out. It's buried in the web worker - and the various frameworks layered on top. I couldn't find a straight answer for it.

.... and don't call me Shirely ....

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [16 March 2026 11:13 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/7 "2026-03-16T11:13:10Z")

</div>

> [@knolleary](#):
>
> It's buried in the web worker

Ah, is the web worker something that has been generated? Sorry, I've not looked at the WW in D2.

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [16 March 2026 11:19 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/8 "2026-03-16T11:19:14Z")

</div>

> [@knolleary](#):
>
> We've seen similar issues with the service worker and I have spent hours trying to figure out how to fix it. In the end, the only reliable fix I could find was to disable the service worker entirely (which you can do in the dashboard base config node).

I'm curious to know, where is that setting? Is that `Allow App Installation`, because I can't seem to find anything that says disable service worker. I really don't want to disable `Allow App Installation`.

I might take a stab at the service worker myself, but if you've already spent hours then I'm not sure I would be much more successful.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [16 March 2026 11:20 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/9 "2026-03-16T11:20:43Z")

</div>

Never mind, I can see that it uses Workbox.

So Workbox _does_ expose `fetchDidSucceed` and `fetchDidFail` on routes.

So you need some kind of auth plugin for workbox - Claude suggested a possible solution that might be worth looking at?

[https://claude.ai/share/c7d7d3b2-ca9d-4d9f-94f4-a036156e1c99](https://claude.ai/share/c7d7d3b2-ca9d-4d9f-94f4-a036156e1c99)

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [16 March 2026 13:07 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/10 "2026-03-16T13:07:22Z")

</div>

I'm trying this change now, and with 15 minute session length in Cloudflare, I haven't reproduce the issue yet.

> **[Comparing FlowFuse:main...pakerfeldt:fix-sw-auth-proxy ·...](https://github.com/FlowFuse/node-red-dashboard/compare/main...pakerfeldt:node-red-dashboard:fix-sw-auth-proxy)**
>
> Contribute to FlowFuse/node-red-dashboard development by creating an account on GitHub.

I admit this change was done with the help of Opus 4.6, and I don't exactly know if there's any major downsides of this.

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [17 March 2026 09:18 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/11 "2026-03-17T09:18:11Z")

</div>

Alright, a bit of update here. It turned out I wasn't actually testing my fix, because the old sw.js was cached in /data/node\_modules/@flowfuse/node-red-dashboard. So had to delete this, and re-install my own build of the dashboard node. Not entirely sure why it seemed to work regardless, but I suspect the session didn't really expire after 15 minutes as I thought.

Anyway, an easier way to trigger this is to revoke the tokens in Cloudflare console, as it's immediate. Now with the new service worker in place, I've verified that after installing the PWA, and revoking the tokens, a reload of the page redirects me to the Cloudflare sign-in page. I think this is the ultimate verification that the fix indeed solves my problem.

It's my understanding that the main difference is that page navigations now, instead of reaching the cache, goes over network. I can personally live with that over having to reinstall the PWA on a monthly basis.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [17 March 2026 09:48 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/12 "2026-03-17T09:48:29Z")

</div>

Is your built fork available on github for us to install to try it?

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [17 March 2026 10:09 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/13 "2026-03-17T10:09:52Z")

</div>

I have not deployed it to npm, so you would have to build a version yourself using my branch.

The change is here:

> **[GitHub - pakerfeldt/node-red-dashboard at fix-sw-auth-proxy](https://github.com/pakerfeldt/node-red-dashboard/tree/fix-sw-auth-proxy)**
>
> Contribute to pakerfeldt/node-red-dashboard development by creating an account on GitHub.

I run my Node-RED instance in docker compose and build the image with a custom Dockerfile.

Here's the relevant snippet of my Dockerfile.

```auto
# Skip the official node for now
#RUN npm install @flowfuse/node-red-dashboard@1.30.2

# Clone, build, then install the patched dashboard
RUN git clone --branch fix-sw-auth-proxy https://github.com/pakerfeldt/node-red-dashboard.git /tmp/node-red-dashboard
WORKDIR /tmp/node-red-dashboard
RUN npm install && npm run build
WORKDIR /usr/src/node-red
RUN npm install /tmp/node-red-dashboard

```

Then on my phone, I had to unregister the cached service worker by connecting the phone to my Mac, use Safari to open Dev Tools and inspect the tab running my dashboard, and then run this in the console:  
`navigator.serviceWorker.getRegistration().then(r => r.unregister()).then(() => location.reload())`  
To force the new version to be downloaded. Then I could install it as PWA again.  
This last step of ensuring the new service worker gets downloaded is probably doable with other means as well. Like making sure you clear the entire Safari cache.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [17 March 2026 10:24 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/14 "2026-03-17T10:24:53Z")

</div>

OK, I know how to build it. I will give it a go later.

First I am running the original again installed as PWA to make sure I still see a problem.

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [17 March 2026 10:42 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/15 "2026-03-17T10:42:36Z")

</div>

Unfortunately. The fix was incomplete. It seems as if revoking tokens explicitly, and waiting for one to expire, doesn't really trigger the same behavior. As I was returning to the PWA after a while, I got the error screen in Dashboard 2 again. So I'm exploring more changes now, will report back later.

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [17 March 2026 12:57 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/16 "2026-03-17T12:57:34Z")

</div>

My first attempt had the problem that revoking the tokens manually in Cloudflare seem to work, but as the token expired, redirection did not work. I then had a few follow-up attempts and landed in what's currently on [this branch](https://github.com/pakerfeldt/node-red-dashboard/tree/fix-sw-auth-proxy). For some reason, this change does _not_ work when revoking the tokens manually. In this case, the page ends up in a redirection loop, that can be escaped by clearing the cache. But more importantly, the change seems to properly handle when the token expires which ofc is more crucial.

I've had it expire two times in a row, and in both cases I was successfully redirected to Cloudflare's sign in page. I think this works the way I would expect it.

Seeing that it's unfortunate to run a fork of Dashboard 2.0, I would love to hear @knolleary comments on this, to see if we can get this upstream somehow.

---

<div class="post-metadata">

### Author: ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)
#### Post date: [17 March 2026 13:00 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/17 "2026-03-17T13:00:41Z")

</div>

Great work! Though I think that you need to put something in to prevent the redirection loop as that is quite devastating to users - it can crash the browser in extreme cases I think.

Can't you put a check in to see if a 301 is going to the same URL on the 2nd time around?

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [17 March 2026 13:08 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/18 "2026-03-17T13:08:10Z")

</div>

> [@TotallyInformation](#):
>
> Great work! Though I think that you need to put something in to prevent the redirection loop as that is quite devastating to users - it can crash the browser in extreme cases I think.
> 
> Can't you put a check in to see if a 301 is going to the same URL on the 2nd time around?

Detecting redirect loops in the SW would require intercepting navigation requests, which is what caused issues with multi-step auth flows. I think the browser's built-in redirect loop protection already handles pathological cases. For example, Safari errors out after 20 attempts.

The approach here is deliberately minimal: remove the SW from the navigation path entirely and let the browser handle auth redirects natively.

---

<div class="post-metadata">

### Author: ![pakerfeldt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/pakerfeldt/32/3101_2.png) [@pakerfeldt](https://discourse.nodered.org/u/pakerfeldt)
#### Post date: [18 March 2026 08:18 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/19 "2026-03-18T08:18:19Z")

</div>

I've created [an issue](https://github.com/FlowFuse/node-red-dashboard/issues/2068) and [a PR](https://github.com/FlowFuse/node-red-dashboard/pull/2069) and I hope a discussion on how to solve this upstream can continue there.

---

<div class="post-metadata">

### Author: ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)
#### Post date: [18 March 2026 09:46 UTC](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574/20 "2026-03-18T09:46:49Z")

</div>

I don't know if this is related or not, but for awareness, recently changes were done in iOS/macos - it will [no longer allow websocket connections over ip addresses](https://www.reddit.com/r/webdev/comments/1pzmhvf/websocket_broken_on_safariios_26/) - it requires a DNS name. If the dashboard connects over local ip, it won't work.

[Next page](https://discourse.nodered.org/t/dashboard-2-0-pwa-service-worker-prevents-authentication-redirect-when-session-expires/100574.md?page=2)
