#36239·bitcoin

RFC: Hazards of the modern unprivileged Guix daemon configuration

Author: hebastoCreated Sep 13, 2026Updated Sep 17, 2026
LabelsBrainstormingBuild system

According to the Guix documentation, there are two ways to configure the Guix daemon:

  1. running guix-daemon as "root", letting it run build processes as unprivileged users taken from a pool of build users...
  2. running guix-daemon as a separate unprivileged user, relying on Linux's unprivileged user namespace functionality to set up isolated environments...

The latter is the option chosen when installing Guix on a systemd-based distribution with the installation script.

Unfortunately, the two configurations produce observably different build environments. Consequently, some packages' test suites fail on the unprivileged daemon. Some of those packages are dependencies of our Guix environments. For example, here is the test failure for python-distlib:

=================================== FAILURES ===================================
_______________________ FileOpsTestCase.test_is_writable _______________________

self = <test_util.FileOpsTestCase testMethod=test_is_writable>

def test_is_writable(self):
  sd = 'subdir'
  ssd = 'subsubdir'
  path = os.path.join(self.workdir, sd, ssd)
  os.makedirs(path)
  path = os.path.join(path, 'test')
  self.assertTrue(self.fileop.is_writable(path))
  if os.name == 'posix':
>           self.assertFalse(self.fileop.is_writable('/etc'))
E           AssertionError: True is not false
tests/test_util.py:721: AssertionError

Users with an unprivileged daemon encounter such errors whenever a dependency is built locally rather than substituted, either because they pass --no-substitutes or because no substitutes exist for their platform (for example, on RISC-V systems). On x86_64 and aarch64 the problem is masked by substitutes, which are built on Guix's build farm with the privileged daemon.

Although failures of this class are known upstream, we should address the issue at the Bitcoin Core project level as well.

Here are some possible approaches:

  1. Provide a shell script that detects the Guix daemon configuration and warns about the unprivileged one.
  2. Document a migration path from the unprivileged daemon to the privileged one (note that Guix documents the migration in the opposite direction only).