Skip to content

ThunderHub SSO login fails with EACCES when .cookie is owned by root #1072

Description

@Perlover

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

  1. 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).
  2. Open Server Settings → Services → ThunderHub and follow the link.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions