Summary
The bitcoin_thub container runs as uid=1000 (node), while btcpayserver runs
as root. Both mount the shared volume lnd_bitcoin_thub_datadir.
ThunderHub calls refreshCookie() on every SSO login and needs write access
to /data/.cookie. When that file ends up owned by root:root (mode 644),
ThunderHub can read it but not rewrite it, and login fails.
Symptom
Clicking the ThunderHub link in BTCPay (Server Settings → Services) opens a new
tab that immediately closes. No error is shown in the UI — the failure is only
visible in the container log.
Error
Error: EACCES: permission denied, open '/data/.cookie'
at FilesService.refreshCookie (/app/dist/modules/files/files.service.js:337:19)
at AuthResolver.getAuthToken (/app/dist/modules/api/auth/auth.resolver.js:181:31)
at /app/node_modules/@nestjs/core/helpers/external-context-creator.js:67:33
at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
Why it is easy to miss
Whether this happens depends on which container creates the cookie file first:
- if ThunderHub creates it → owner is
node, everything works, possibly for years;
- if BTCPay creates it (container recreation, restore from backup, changed start
order) → owner is root, and SSO silently breaks.
On the affected instance the file was dated several months before the problem was
noticed, so the breakage went unnoticed for a long time — the ThunderHub link is
not used daily, and the closing tab looks like a browser quirk rather than an error.
Reproduce
- Ensure
/data/.cookie in the lnd_bitcoin_thub_datadir volume is owned by
root:root with mode 644 (e.g. let BTCPay create it, or chown root:root it).
- Open
Server Settings → Services → ThunderHub and follow the link.
- The tab opens and closes;
docker logs generated_bitcoin_thub_1 shows the
EACCES trace above.
Environment
- ThunderHub image:
apotdevin/thunderhub:base-0.15.4
- Fragment:
opt-add-thunderhub
bitcoin_thub runs as uid=1000 (node), btcpayserver runs as uid=0 (root)
- Shared volume:
lnd_bitcoin_thub_datadir → /data (thub) and
/etc/lnd_bitcoin_thub_datadir (btcpayserver)
Workaround
chown -R 1000:1000 /var/lib/docker/volumes/generated_lnd_bitcoin_thub_datadir/_data
docker restart generated_bitcoin_thub_1
Suggested fix
Make ownership deterministic instead of dependent on start order — either
chown the thub datadir to 1000:1000 in the fragment / entrypoint, or
- have BTCPay create the cookie file with ownership matching the ThunderHub
container, or
- create the file with mode
666 (least preferable).
Since the ThunderHub image deliberately drops privileges, aligning the volume
ownership on the BTCPay side seems the cleanest option.
Summary
The
bitcoin_thubcontainer runs asuid=1000 (node), whilebtcpayserverrunsas
root. Both mount the shared volumelnd_bitcoin_thub_datadir.ThunderHub calls
refreshCookie()on every SSO login and needs write accessto
/data/.cookie. When that file ends up owned byroot:root(mode644),ThunderHub can read it but not rewrite it, and login fails.
Symptom
Clicking the ThunderHub link in BTCPay (
Server Settings → Services) opens a newtab that immediately closes. No error is shown in the UI — the failure is only
visible in the container log.
Error
Why it is easy to miss
Whether this happens depends on which container creates the cookie file first:
node, everything works, possibly for years;order) → owner is
root, and SSO silently breaks.On the affected instance the file was dated several months before the problem was
noticed, so the breakage went unnoticed for a long time — the ThunderHub link is
not used daily, and the closing tab looks like a browser quirk rather than an error.
Reproduce
/data/.cookiein thelnd_bitcoin_thub_datadirvolume is owned byroot:rootwith mode644(e.g. let BTCPay create it, orchown root:rootit).Server Settings → Services → ThunderHuband follow the link.docker logs generated_bitcoin_thub_1shows theEACCEStrace above.Environment
apotdevin/thunderhub:base-0.15.4opt-add-thunderhubbitcoin_thubruns asuid=1000 (node),btcpayserverruns asuid=0 (root)lnd_bitcoin_thub_datadir→/data(thub) and/etc/lnd_bitcoin_thub_datadir(btcpayserver)Workaround
Suggested fix
Make ownership deterministic instead of dependent on start order — either
chownthe thub datadir to1000:1000in the fragment / entrypoint, orcontainer, or
666(least preferable).Since the ThunderHub image deliberately drops privileges, aligning the volume
ownership on the BTCPay side seems the cleanest option.