Nix-daemon.{socket,service} not recognized on boot (Nix overlay on Gentoo)

My main workstation runs Gentoo as the base OS, with Nix overlaid. On a fresh boot, nix-daemon.socket is not initialized automatically. I have to run systemctl daemon-reload && systemctl start nix-daemon.socket as root, after the system is fully booted, to be able to do anything with Nix.

It is probably relevant that the unit files for nix-daemon.service and nix-daemon.socket are sourced from the Nix store, which is not on the root filesystem:

# ls -l /etc/systemd/system/nix*
lrwxrwxrwx 1 root root 67 Mar 18  2025 /etc/systemd/system/nix-daemon.service -> /nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.service
lrwxrwxrwx 1 root root 66 Mar 18  2025 /etc/systemd/system/nix-daemon.socket -> /nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.socket
# findmnt --target /nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.socket
TARGET     SOURCE                   FSTYPE OPTIONS
/nix/store /dev/md127p2[/nix-store] xfs    rw,nosuid,nodev,relatime,attr2,inode64,logbufs=8,logbsize=32k,sunit=1024,swidth=1024,noquota

So my guess as to what’s wrong is that when systemd initially reads all the unit files, these two are dangling symlinks, and it has no way of knowing that mounting /nix/store will correct that. But I don’t know how to fix this. If there is a way to tell systemd that it needs to mount a particular filesystem before it can read a particular unit file, I can’t find it in systemd’s maze of manpages. Does anyone know the trick?

Got some help from people elsewhere. There isn’t any built-in way to tell systemd that it needs to mount a particular partition before it can read one of its unit files, but you can kludge it with a “path” unit. Save this file as /etc/systemd/system/nix-daemon-units.path

[Unit]
Description=Watch for linked Nix unit files

[Install]
WantedBy=sockets.target

[Path]
DirectoryNotEmpty=/nix/var/nix/profiles/default/lib/systemd/system

and this file as /etc/systemd/system/nix-daemon-units.service

[Unit]
Description=Reload systemd unit configuration when Nix units become available

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemctl daemon-reload
ExecStart=/usr/bin/systemctl start nix-daemon.socket

and then do systemctl enable nix-daemon-units.path; reboot as root. The .path file makes systemd watch for files to appear in the directory where nix-daemon.{service,socket} actually live. When they do, it triggers the matching .service file, which reloads the service configuration (picking up the newly available unit files) and activates the listening socket for the Nix daemon. You need both the ExecStart lines, because daemon-reload alone doesn’t re-trigger units that are enabled but failed earlier.

1 Like