Zroot/home not mounted in stage-1-init using zfs with disko

I am experiencing a problem where my home dataset, zroot/home, gets mounted too late which means that the users activationScript which creates my user’s home directory gets installed into zroot/rootinstead of zroot/home. Afterwards systemd mount zroot/home which creates a shallow empty /home directory. So i don’t have any home directory for my user. The order of operations is the following:

  • stage-1-init: All datasets except zroot/home gets mounted.
  • activation script runs installing the users home directory to zroot/root since zroot/home is not mounted yet
  • systemd (home.mount) mounts zroot/home which means that /home is now empty

The journal says:


Apr 10 10:31:57 nixos systemd[1]: home.mount: Directory /home to mount over is not empty, mounting anyway.
Apr 10 10:31:57 nixos systemd[1]: Mounting /home…
Apr 10 10:31:57 nixos systemd[1]: Mounted /home.

In dmesg you can see that all the datasets (except zroot/home) gets mounted in stage-1-init:

[    1.026109] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] starting device mapper and LVM...
[    1.120151] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] importing root ZFS pool "zroot"...
[    1.134629] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting zroot/root on /...
[    1.139377] usb 1-1: new full-speed USB device number 2 using uhci_hcd
[    1.164114] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting zroot/nix on /nix...
[    1.176111] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting nix-store on /nix/.ro-store...
[    1.179237] 9p: Installing v9fs 9p2000 file system support
[    1.185017] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting tmpfs on /nix/.rw-store...
[    1.195197] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting overlay on /nix/store...
[    1.210647] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting shared on /tmp/shared...
[    1.218098] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting xchg on /tmp/xchg...
[    1.226101] stage-1-init: [Fri Apr 10 08:31:55 UTC 2026] mounting zroot/var on /var...

Here is my disko config:

{
lib, 
pkgs,
rootDisk,
rootDiskSize ? "100%",
raidz1DisksSize ? "100%",
raidz1Disks,
bootSize,
swapSize,
...
}: {
    networking.hostId = "deadbeef";

    environment.systemPackages = with pkgs; [
      zfs
    ];

    boot.zfs.devNodes = lib.mkDefault "/dev/disk/by-path";
    disko.devices = {
      disk =
        {
          main = {
            type = "disk";
            device = rootDisk;
            imageSize = rootDiskSize;
            content = {
              type = "gpt";
              partitions = {
                boot = {
                  size = bootSize;
                  type = "EF00";
                  content = {
                    type = "filesystem";
                    format = "vfat";
                    mountpoint = "/boot";
                    mountOptions = ["umask=0077"];
                  };
                };
                swap = {
                  size = swapSize;
                  content = {
                    type = "swap";
                    discardPolicy = "both";
                    resumeDevice = true;
                  };
                };
                root = {
                  size = "100%";
                  content = {
                    type = "zfs";
                    pool = "zroot";
                  };
                };
              };
            };
          };
        }
        # just a helper for joining all raid disks to the raid
        // lib.attrsets.genAttrs raidz1Disks (name: {
          type = "disk";
          device = "/dev/${name}";
          imageSize = raidz1DisksSize;
          content = {
            type = "gpt";
            partitions = {
              zfs = {
                size = "100%";
                content = {
                  type = "zfs";
                  pool = "storage";
                };
              };
            };
          };
        });

      zpool = {
        zroot = {
          type = "zpool";
          rootFsOptions = {
            mountpoint = "none";
            canmount = "off";
            acltype = "posixacl";
            xattr = "sa";
            atime = "off";
          };

          options = {
            ashift = "12"; # 4K blocksize
            autotrim = "on";
          };

          datasets = {
            root = {
              type = "zfs_fs";
              mountpoint = "/";
            };
            nix = {
              type = "zfs_fs";
              mountpoint = "/nix";
            };
            var = {
              type = "zfs_fs";
              mountpoint = "/var";
            };
            home = {
              type = "zfs_fs";
              mountpoint = "/home";
            };
          };
        };

        storage = lib.mkIf (builtins.length raidz1Disks > 0) {
          type = "zpool";
          mode = "raidz";

          rootFsOptions = {
            mountpoint = "none";
            acltype = "posixacl";
            xattr = "sa";
            atime = "off";
          };

          datasets = {
            data = {
              type = "zfs_fs";
              mountpoint = "/data";
            };
          };
        };
      };
    };
  };
}

I dont understand why home doesnt just get mounted like the other datasets. I have tried to solve this by:

  • Setting options.mountpoint = “legacy” - didn’t do anything
  • setting fileSystems.”/home”.neededForBoot = true - didn’t help
  • Switching to systemd in initrd (boot.initrd.systemd.enable) - I read that this could help but didnt change anything.

If i remove zroot/home everything works as expected since it just uses zroot/root.

I am testing this with disko vm, which creates a qemu vm with and uses disko to format the disks:
nix run -L ‘.#nixosConfigurations.hostname.config.system.build.vmWithDisko’