Hi! First of all, I wanted to thank you for creating this tool and making it so accessible. It really looks amazing. Despite all my efforts to make this work, I just can't make it work. I've tried on CachyOS (based on Arch Linux) and on my UGreen DXP2800 and I always get the same issue : after running the installer, I can access the dashboard (IP:8443) but it never shows anything; it just shows : "Could not load modules" when I go into "Apps" and "Could not load modules" when I go back into "Home" I then tried "sudo sparkbox install" or "sudo sparkbox config" which then brings up the installer in the blue screen where I get to pick what I want (jellyfin and searxng) or "sudo sparkbox up" but in all instances, it always shows the same error messages in the dashboard. Any help would be greatly appreciated :)
14 replies
tomspark wrote:
Welcome — and that's our bug, not your setup if two different machines throw the same error. The dashboard page itself loads but its /api/modules call is failing inside, which is what makes the page look empty. Two diagnostics tell me where to dig: 1. With the dashboard open in your browser, press F12 → Network tab → refresh → find the red /api/modules row → click it → Response tab. Paste whatever's there (status code + body). 2. In a terminal on the host: sudo docker logs sb-dashboard --tail 30 That shows the matching server-side error. Paste both and I'll have a fix path quickly — we're on v1.6.109 right now.
jono1084 wrote:
Thanks for the quick reply :) Question : when running "sparkbox install/config", should I run it as sudo? or just "sparkbox install" straight up? This is what I see : 1. Response : {"error":"Unauthorized"} 2. sudo docker logs sb-dashboard --tail 30 : Error: EACCES: permission denied, open '/app/state/sessions/Ltc94sUbl5AYXy6frlE5qQyTz9K3NoM.json.1.1778719207095.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/xXptaUTPJNg4S49IPtI4rj5UUUxXCy8u.json.1.1778719212098.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/CMxfJXdSrqy4HHVR7GwvBd97D0RuLcgM.json.1.1778719216092.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/X2BYqZV26i-mhDeL7MGvXVt5FzZrVnqR.json.1.1778719216389.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/26YFewWwQH-8NdklPIRP2KeyV6zDM7L4.json.1.1778719225094.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/Cei-gdli0IuAJA5j16QmCbEZSoqUPWyj.json.1.1778719234094.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/m26ij88qFxL2xZslaVeyDSniwpGcjpZs.json.1.1778719242093.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/sx9RPSAmWFtCkdCcgusM84nC4fWbmYq.json.1.1778719243093.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/hM4xBsrXLAEsJKoOpmNfDMODmqms2so.json.1.1778719246486.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14) Error: EACCES: permission denied, open '/app/state/sessions/B9-Uv5VrO5MZRcuzPTFaMLf3niWGLRyp.json.1.1778719252093.tmp' at async open (node:internal/fs/promises:637:25) at async Object.writeFile (node:internal/fs/promises:1219:14)
tomspark wrote:
Found it. The dashboard container can't write to state/sessions/ because the dir is owned by root, but the dashboard inside the container runs as UID 1000. Same class as v1.6.75 but slipped through on fresh installs. One-line fix on your end: sudo chown -R 1000:1000 /opt/sparkbox/state && sudo docker restart sb-dashboard Wait ~10 seconds, refresh the dashboard, and try the bootstrap-claim flow again. Should clear the 401 and the EACCES loop. The /api/modules call will succeed and you'll see your apps. Quick answer to your other question: yes, always run sparkbox commands with sudo — the CLI touches /opt/sparkbox files owned by root and needs to run docker compose. sparkbox install/config/up all assume root. Shipping a proper install.sh fix in the next patch so nobody else hits this — thanks for the diagnostic, that was the gold-standard repro.
tomspark wrote:
v1.6.110 is live with the install-time fix — install.sh now chowns state/ + state/sessions/ to PUID:PGID before the dashboard boots. So nobody else hits this on a fresh install going forward. No action needed on your end (the manual chown already healed your install).
jono1084 wrote:
Thanks for the quick fix :) I can now access the dashboard and see all my apps Is it normal however that I don't see the VPN status on the top of the dashboard? I see that gluetun is running I already tried running sudo sparkbox restart media
tomspark wrote:
Glad the dashboard's loading apps now. For the missing VPN banner: could be either (a) gluetun container is up but the tunnel itself didn't establish (bad creds, wrong SERVERCITIES, missing /dev/net/tun), or (b) tunnel's fine but the dashboard's status-poll has a separate issue. Quick way to tell which side broke: sudo sparkbox doctor It has a [VPN Tunnel] probe that surfaces gluetun's actual state plus its last error line if there is one. Paste just the [VPN Tunnel] section and I'll pinpoint the side. If doctor says VPN is healthy but the banner's still missing, F12 → Network → reload dashboard → look for the vpn-status request and paste its response — that'd point at a frontend polling bug, different fix path.
jono1084 wrote:
When I run "sudo sparkbox doctor" , it doesn't show me anything related to [VPN]. It just shows : sudo sparkbox doctor / | | | | ) \ \| ' \ / | '| |/ / \ / \ \/ / ) | |) | (| | | | <| |) | () < |/| ./ \,|| ||\\/ \//\\ || SparkBox v1.6.110 - Self-Hosted Privacy Stack Created by Tom Spark | youtube.com/@TomSparkReviews Environment: NAS (ugreen) SparkBox Doctor Running diagnostics... [Docker] [OK] Docker daemon is accessible [OK] Docker version: Docker version 26.1.0, build 9714adc [OK] Docker Compose: 2.26.1 [Docker Socket] [OK] Docker socket exists at /var/run/docker.sock [OK] Docker socket is readable [User IDs] [INFO] Current user: root (UID=0, GID=0) [OK] PUID=1000 (containers run as UID 1000) [OK] PGID=10 (containers run as GID 10) [Container Egress] [OK] Containers can reach webhook.tomsparkbox.com (license server) [Port Conflicts] [OK] Port 53: available [WARN] Port 80: in use by non-Docker process LISTEN 0 511 0.0.0.0:80 0.0.0.0: users:(("nginx",pid=1694399,fd=6),("nginx",pid=1694398,fd=6),("nginx",pid=1694397,fd=6),("nginx",pid=1694396,fd=6),("nginx",pid=7540,fd=6)) -------------------------- As for the F12 → Network → reload dashboard, I don't see anything related to "vpn-status" but I do see an entry "status" that says : { "mediaenabled": false, "message": "Media Center module is not enabled. Enable it to route downloads through a VPN." }
tomspark wrote:
Two things from your output: 1. doctor is crashing silently after [Port Conflicts] — should print [Portainer Auth] / [VPN Tunnel] / [Hardware Transcoding] sections after that. The WARN on port 80 (your nginx) is likely tripping a bash set-e gate. That's a doctor bug on our side, separate issue I'll fix. 2. The real answer to your missing banner: /api/status says mediaenabled: false. The VPN banner only renders when the media module is enabled — it exists to protect arr/qbit downloads. You picked jellyfin + searxng and skipped the media bundle, so no banner is the correct state, not a bug. If you want the banner anyway, sudo sparkbox config → enable media → sudo sparkbox up. If you don't want the arr stack, you're fine as-is.
jono1084 wrote:
edit : I went in dashboard Apps Profiles Clicked on "Media". It then prompted me "do you want to enable Media profile?" I clicked on yes and I now see the VPN bar at the top, sorry for the confusion!
tomspark wrote:
No apology needed — that's the right call. The dashboard's Profiles tile is the cleaner path than CLI. Enjoy the arr stack.
siv wrote:
I did an install couple hours ago @tomspark still had the same issue as the original post. Tried to appy the manual chown as you'd explained but got this error after restarting.
tomspark wrote:
Hey siv — that's a different error than jono hit. The chown got your dashboard loading, but the wizard's setup-apply step is failing downstream when it tries to save settings or start the selected apps. The red banner's a generic surface message; the real cause is almost always in setup-apply.log. Three things to paste so I can pinpoint: sudo cat /opt/sparkbox/state/setup-apply.log | tail -30 cat /opt/sparkbox/VERSION df -h /opt/sparkbox Treating this as our bug not your environment — the install shouldn't punt to 'check Docker / check disk space' as the user-facing answer if those are fine.
siv wrote:
Got it working now I think here's a summary of what was happening with me: I managed to get it working. My setup: Windows 10 Ubuntu WSL2 installed on D drive Docker Engine installed inside WSL, not Docker Desktop SparkBox v1.6.105 fresh install Issue: The dashboard loaded but setup/session actions were failing with permission errors. The dashboard logs showed: text EACCES: permission denied, open '/app/state/sessions/...json.tmp' EACCES: permission denied, open '/app/.env' So it was not just state/sessions; the dashboard also needed write access to /opt/sparkbox/.env, because /app inside the container maps to /opt/sparkbox on the WSL host. The original suggested fix was: bash sudo chown -R 1000:1000 /opt/sparkbox/state && sudo docker restart sb-dashboard For my install, I also had to apply ownership to .env: bash sudo docker stop sb-dashboard sudo chown -R 1000:1000 /opt/sparkbox/state sudo chown 1000:1000 /opt/sparkbox/.env sudo chmod -R 700 /opt/sparkbox/state sudo chmod 600 /opt/sparkbox/.env sudo docker start sb-dashboard After that, the dashboard logs no longer showed new EACCES errors and the dashboard worked at: text http://localhost:8443 One thing to note: https://localhost showed the Nginx Proxy Manager default page / SSL issue in my setup, but the direct dashboard port worked correctly: text http://localhost:8443
tomspark wrote:
siv that writeup is gold — diff-style dual-EACCES analysis pointed straight at the root cause. Shipped v1.6.112 just now (curl -s https://get.tomsparkbox.com/releases/latest/version.txt confirms). install.sh now chowns .env to 1000:1000 right after writing it, and the sparkbox CLI also re-chowns it on every sparkbox up so a manual root-edit of .env doesn't re-break the dashboard later. Fresh installs from this point won't hit the wizard red banner. On the https://localhost / NPM default page thing — that's expected and unrelated. NPM listens on 443 but doesn't have a SparkBox-side default proxy host for localhost configured. Use http://NAS-IP:8443 for the dashboard until you set up your real hostname through NPM, which the dashboard's Custom Domain wizard automates. Thanks again for the rigor on the EACCES log diff — that's the kind of report that closes a bug in one round.