Skip to content

Permission denied

"Permission denied" in HiveCast can mean four very different things. Identify which class you're seeing first.

Class A — Filesystem permissions on <host-home>

Symptoms:

  • EACCES: permission denied, open '/var/lib/hivecast/host.status.json'
  • EPERM: operation not permitted, mkdir '/tmp/matrix-home/runtimes/...'
  • The hivecast CLI runs but can't write logs

Cause

Either:

  • <host-home> is owned by a user different from the one running hivecast (very common after dpkg -i postinst — the install runs as root, the workstation user owns home).
  • <host-home> was created with 0750 mode and o-rwx blocks the running user.
  • A subdirectory was created by a different user (e.g. someone ran sudo hivecast start once, leaving root-owned files).

Fix

bash
# Check ownership
ls -ld <host-home>
ls -la <host-home>/

# If wrong, chown everything to the correct user
sudo chown -R <user>:<group> <host-home>

For .deb installs, the postinst sets ownership to ${SUDO_USER} (the workstation user) when sudo dpkg -i is run by a real user. If postinst couldn't determine the user, ownership defaults to the hivecast system user.

bash
# After dpkg -i hivecast.deb, fix ownership to your workstation user
sudo chown -R "$USER:$(id -gn)" /var/lib/hivecast

If you want services to run as hivecast and your user can't access /var/lib/hivecast, that's the design — use sudo systemctl status hivecast-host.service to inspect, and journalctl for logs.

Class B — Service-manager permissions

Symptoms:

  • Failed to start hivecast-host.service: Unit not found
  • Authentication is required (polkit prompt)
  • Permission denied running systemctl commands

Cause

You're running systemctl without sudo, or the unit files weren't installed into /lib/systemd/system/.

Fix

bash
# Most systemctl operations need sudo
sudo systemctl status hivecast-host.service hivecast-nats.service
sudo systemctl restart hivecast-host.service

# Verify the unit files exist
ls -la /lib/systemd/system/hivecast-*.service

# If missing, the .deb install didn't complete
sudo apt install --reinstall hivecast

User-mode systemd (systemctl --user) is not what HiveCast uses; the .deb install puts units in the system slice.

Class C — NATS auth failure (browser-side)

Symptoms in the browser console:

  • nats: Authorization Violation
  • WebSocket close with code 1008 (policy violation)
  • "User not authorized to publish on subject ..."

Cause

The browser's NATS connection authenticated, but with a credential that doesn't have permission for the subject the page tried to use.

Per CLAUDE.md Rule 7:

Browser connects via same-origin WebSocket. Always /nats-ws on the SAME origin. Never absolute WebSocket URLs from bootstrap.

The browser inherits the page's session context. On a local-client Host, the loopback-trust gives the browser broad permissions. On a public-session Host, the OAuth-derived session decides what subjects the browser can use.

If the browser shows auth violations, the session is anonymous / unauthenticated when it tried something an authenticated user could do.

Fix

  • Confirm the page reached the gateway with a valid session: check the response of /api/auth/me from the page.
  • For local-client Hosts: confirm the browser is loading from 127.0.0.1 or localhost, not from a non-loopback hostname (which won't trip the local-owner trust).
  • For public-session Hosts: re-sign-in. The session may have expired.

Class D — OAuth provider permissions

Symptoms:

  • After OAuth callback: "This app is not allowed to access your account"
  • redirect_uri_mismatch from Google / GitHub
  • unauthorized_client

Cause

The OAuth credentials configured for the Host don't match what the provider expects:

  • The redirect URI registered with Google doesn't match the Host's actual callback URL.
  • The OAuth client is in test mode and your account isn't whitelisted.
  • The client secret is wrong / rotated.

Fix

For self-hosted Hosts: verify the OAuth provider config (in host.json auth.providers.google or via env vars). The redirect URI registered with the provider must exactly match the Host's <external-url>/api/auth/callback/<provider>.

For hivecast.ai: this should never happen in production. If it does, report it.

Class E — File mode on the bundled NATS binary

Symptoms:

  • nats-server: Permission denied when the wrapper tries to spawn it.

Cause

The bundled binary lost its executable bit. The wrapper's copyFileIfPresent sets mode 0o755 (hivecast.mjs:391); the .deb install's chmodSync(.../bin/nats-server, 0o755) does the same. But if you copied <host-home>/bin/nats-server from one place to another, the executable bit may have been lost.

Fix

bash
chmod 0755 <host-home>/bin/nats-server
hivecast start --home <host-home>

Class F — runtimes/<id>/ ownership mismatch after a different user ran the Host

Symptoms:

  • EACCES writing to a specific runtime's record directory
  • hivecast doctor flags some runtimes as inaccessible

Cause

Someone ran hivecast start as a different user once (e.g. as root), and that user's runtimes are owned by them.

Fix

bash
sudo chown -R <correct-user>:<correct-group> <host-home>/runtimes/

See also

Source: projects/matrix-3/packages/hivecast/scripts/build-deb-installer.js lines 296-302 (/var/lib/hivecast ownership setup); projects/matrix-3/packages/host-service/src/types.ts lines 39-49 (IHostAuthConfig); repo-root CLAUDE.md Rules 4-7 (auth boundaries, browser → NATS).