users.users.<name>.createHome not creating home directory

I’m trying to figure out how to set up a Nix system with tmpfs as / and /home, ZFS for the persistent storage, the Impermanence module for managing persistent files, and a Flake-based config.

It’s mostly working, but my user’s home directory doesn’t get created even though I have users.users.eufalconimorph.createHome = true;.

In configuration.nix:

users = {
  mutableUsers = false;
  users = {
    root.hashedPassword = "!"; # Disable root login
    eufalconimorph = {
      isNormalUser = true;
      description = "Eufalconimorph";
      home = "/home/eufalconimorph";
      createHome = true;
      passwordFile = "/persist/etc/users/eufalconimorph";
      extraGroups = [ "wheel" "networkmanager" "audio" "dialout" "docker" "dumpcap" ];

Relevant bit (I think) of hardware-configuration.nix:

fileSystems."/home" =
  { device = "tmpfs";
    fsType = "tmpfs";
    options = [ "defaults" "size=2G" "mode=755" ];

fileSystems."/home/persist" =
  { device = "rpool/safe/home";
    fsType = "zfs";

And then in home.nix I set up directories to persist with `home.persistence.“/home/persist/eufalconimorph” = { # stuff };

At login, /home/eufalconimorph doesn’t get created. Graphical login fails, unless I login manually to a terminal & make the directory (and change owner). Home-manager fails to start at boot (probably because there’s no home directory).

Edit: I could (of course) add commands to make & change owner of the directory in boot.initrd.postMountCommands, but that seems like a nasty hack.

I would appreciate any advice.

This is just wild speculation, so take it with a very large grain of salt: Does the user account already exist? Maybe the logic to create the directory is only triggered if the account is being created.

I don’t see how it could, given that / is tmpfs.

I “solved” the issue by changing the fileSystems."/home" tmpfs to fileSystems."/home/eufalconimorph", but of course that doesn’t really work if you have multiple users. It’s a single-user system, but it feels wrong to limit it that way. I was hoping to make it generic enough to serve as an example, since all the similar examples I can see are missing something.

Yea, there’s an issue for this

We wanted to solve it with a systemd-tmpfiles based solution, but that got blocked on a tmpfiles bug. That bugfix will be in systemd 254, which should be released soon-ish.