How to setup LUKS2 auto unlock with file on usb with fallback to password?

I tried many solutions, with boot.initrd.systemd.mounts, fileSystems.<name>.encrypted, keyFile, etc. I am using nixos unstable.

I have a FAT32 partition with the key at /dev/disk/by-uuid/2989-2930.
The key file in the partition is called lukskey.bin. The luks is called luks-245f537d-f6b9-4e94-9c2f-c5c56a543fa8. The LUKS2 partition is /dev/disk/by-uuid/245f537d-f6b9-4e94-9c2f-c5c56a543fa8. The / partition is BTRFS in the encrypted partition /dev/disk/by-uuid/4f7eb8c6-fd2e-4ca5-b2a2-4d93a984b40f.

If someone can help me try out different configuration, I can post the error messages / describe what happens. Since I tried so many things it would take a long time to post everything I tried and all the results.

Here is the latest thing I tried:

boot.initrd.systemd.mounts = [
    {
      what = "/dev/disk/by-uuid/2989-2930";
      where = "/key";
      type = "vfat";
    }
  ];

  boot.initrd.systemd.enable = true;
  boot.initrd.luks.devices."luks-245f537d-f6b9-4e94-9c2f-c5c56a543fa8" = {
    keyFile = "/key/lukskey.bin";
    keyFileTimeout = 5;
  };

the /key was mounted, but systemd kept waiting 90s for the root partition to be available. Then after it went into rescue mode and I pressed enter, NixOS booted without me having to enter the password. So it’s kind of working but not working.

Where are your fileSystems."/" and boot.initrd.luks.devices."luks-....".device definitions? Hard to say what’s going wrong without seeing the whole picture.

It is in the hardware configuration:

fileSystems."/" = {
    device = "/dev/disk/by-uuid/4f7eb8c6-fd2e-4ca5-b2a2-4d93a984b40f";
    fsType = "btrfs";
    options = [ "subvol=@" ];
  };

  boot.initrd.luks.devices."luks-245f537d-f6b9-4e94-9c2f-c5c56a543fa8" = {
    device = "/dev/disk/by-uuid/245f537d-f6b9-4e94-9c2f-c5c56a543fa8";
  };

  fileSystems."/boot" = {
    device = "/dev/disk/by-uuid/411B-EDE1";
    fsType = "vfat";
    options = [
      "fmask=0077"
      "dmask=0077"
    ];
  };

Huh, that’s interesting. I really don’t know why that wouldn’t be working, assuming those two UUIDs are correct