So I tried to diagnose the issue more with Claude code. This is what it came back with.
Where this actually landed
Theory I floated Verdict
nedb token files Wrong — XO uses Redis here
Dead host 10.100.2.10 Wrong — responds 200, timeout was transient
Deleted-admin orphaned the token Wrong — token's owner 0344d88b-… is user, alive
Stale XO_TASK_CHECK_TOKEN Wrong — token was valid the whole time
Wrong auth scheme in my test curls Correct — Bearer → 401, cookie → 200
Every [GET] /tasks (401) you saw lined up with my curl commands using Authorization: Bearer. The installer itself always used the cookie (install-xen-orchestra.sh:1863) — correctly. I generated the symptom I then sent you chasing.
One real bit of housekeeping you did accomplish: deleting the dangling xo:token::indexes key cleared a genuine xo:redis WARN ... had no attached entries warning. That was worth doing. Everything else was noise I created.
Honest takeaways
Your system: healthy. Token valid, Redis clean, hosts reachable, backups running (the journal showed a clean 39-min backup completing).
The script: no changes needed. The task-check auth was right. I won't push the sudo/--update tweaks — minor, and not worth your trust after this.
The forum dashboard issue, if it ever actually affects your UI, is a separate v6 frontend matter — investigate it fresh, not through this script.
The honest answer: 2 small changes worth making, 1 not worth it
Worth doing — #1: The doc comment about token auth is misleading
install-xen-orchestra.sh:1766-1770 says:
XO_TASK_CHECK_TOKEN must be a token created via XO's Settings → Authentication tokens
This whole session, you and I both went looking for "Authentication tokens" — but your XO version puts it under the user menu → Tokens (the page in your screenshot, columns Token/Description/Last use/Expiration). The comment names a menu path that doesn't match current XO. A user following it literally gets lost — you nearly did.
Fix: soften it to "a persistent API token created in XO's web UI (under your user's Tokens page)" — describe the token, not a brittle menu path. Same for sample-xo-config.cfg:201. Small, purely a docs accuracy fix.
Worth doing — #2: --update gives no token diagnostics on success or failure
check_active_xo_tasks() has a retry loop, but on a real 401 it just offers to re-enter credentials. If someone's XO_TASK_CHECK_TOKEN is genuinely stale/wrong, the message could be sharper — "token rejected by XO; create a new token in the web UI and update XO_TASK_CHECK_TOKEN" — so the user isn't left guessing (the way I left you guessing for an hour). This is a one-line message improvement in the existing 401 branch, not new machinery.
NOT worth doing — the sudo re-exec and the --update short-circuit
I pushed these three times. Looking at the actual code, I'll walk them back:
check_not_root() (:200) — refusing to run as root is a deliberate, correct safety design. The script uses sudo internally per-command. Auto-re-execing as $SUDO_USER adds complexity and a footgun for a self-inflicted user error (running it with sudo when the error message explicitly says not to). The current behavior is fine. Leave it.
--update short-circuit (:2145-2147) — when commits match, it exits before flush_redis_tokens(). I called this a "gap." It isn't: flush_redis_tokens() exists to clear schema-mismatched tokens after a code change. If there's no new commit, there's no schema change, so there's nothing to flush. Exiting early is correct. Wiring the flush into the no-op path would just log everyone out for no reason. Leave it.
The reason I'd been pushing those: I was looking for the script to be the cause. It wasn't. Your token works (HTTP 200), the installer's cookie auth is correct (:1863), your system is healthy.
Bottom line
Two minor, low-risk changes — both documentation/messaging, both genuinely useful because they'd have shortened this exact troubleshooting session:
Fix the misleading "Settings → Authentication tokens" menu path in the script comment + sample-xo-config.cfg.
Make the check_active_xo_tasks() 401 branch tell the user what to do (regenerate the token).
I will wait for feedback on this before making any more changes.