ZFS Kernel Module wont load in Raspberry PI 5

Hello dear Nix community. This is my first post, so any meta to what I could improve about the post itself is very welcome :slight_smile:

I am trying to partition a new device with disko on my Raspi 5. The partitioning will use ZFS, so I want to load the kernel module on boot.

Unfortunately, adding zfs to the supported filesystems and the system packages does not seem to be enough. sudo modprobe zfs exits with modprobe: FATAL: Module zfs not found in directory /run/booted-system/kernel-modules/lib/modules/6.12.34. This persists after a nixos-rebuild switch and reboot.

Subsequently, formatting with disko fails as well. I already searched the NixOS Wiki, the internet and debugged with AI but to no avail.

My default.nix for this system is

{
  config,
  pkgs,
  nixos-raspberrypi,
  ...
}:

let
  adminPublicKey = "...";
in
{
  imports = with nixos-raspberrypi.nixosModules; [
    ./hardware-configuration.nix
    raspberry-pi-5.base
    raspberry-pi-5.page-size-16k
    ./pi5-configtxt.nix
    # Binary cache with prebuilt packages for the currently locked `nixpkgs`,
    # see `devshells/nix-build-to-cachix.nix` for a list
    trusted-nix-caches
    ./disko-nvme-ext4.nix
    # ./disko-data-zfs-single.nix
  ];

  boot = {
    loader.raspberryPi.bootloader = "kernel";

    tmp.useTmpfs = true;
    kernelParams = [
      "zfs.zfs_arc_max=200000000" # 200MB
    ];
    supportedFilesystems = [ "zfs" ];
  };

  environment.systemPackages = with pkgs; [
    tree
    btop
    zfs
  ];

  # disko.devices.disk.data1.device = "/dev/sda";
  # disko.devices.disk.data2.device = "/dev/sdb";

  services.zfs.autoScrub.enable = true;
  services.zfs.trim.enable = true;

  networking = {
    # for zfs, must be unique
    hostId = "8821e001";
    hostName = "maximus-zone-aprill";

    useNetworkd = true;
    # Allow mDNS
    firewall.allowedUDPPorts = [ 5353 ];
  };

  # ...

  # We run sshd by default. Login is only possible after adding a
  # password via "passwd" or by adding a ssh key to ~/.ssh/authorized_keys.
  # The latter one is particular useful if keys are manually added to
  # installation device for head-less systems i.e. arm boards by manually
  # mounting the storage in a different system.
  services.openssh = {
    enable = true;
    settings.PermitRootLogin = "yes";
  };

  # allow nix-copy to live system
  nix.settings.trusted-users = [ "nixos" ];

  # We are stateless, so just default to latest.
  system.stateVersion = config.system.nixos.release;

  # Enable mDNS on all networks
  systemd.network.networks = {
    "99-ethernet-default-dhcp".networkConfig.MulticastDNS = "yes";
    "99-wireless-client-dhcp".networkConfig.MulticastDNS = "yes";
  };

  # This comment was lifted from `srvos`
  # Do not take down the network for too long when upgrading,
  # This also prevents failures of services that are restarted instead of stopped.
  # It will use `systemctl restart` rather than stopping it with `systemctl stop`
  # followed by a delayed `systemctl start`.
  systemd.services = {
    systemd-networkd.stopIfChanged = false;
    # Services that are only restarted might be not able to resolve when resolved is stopped before
    systemd-resolved.stopIfChanged = false;
  };

  services.udev.extraRules = ''
    # Ignore partitions with "Required Partition" GPT partition attribute
    # On our RPis this is firmware (/boot/firmware) partition
    ENV{ID_PART_ENTRY_SCHEME}=="gpt", \
      ENV{ID_PART_ENTRY_FLAGS}=="0x1", \
      ENV{UDISKS_IGNORE}="1"
  '';
}

And the root flake is

{
  inputs = {
    nixpkgs-unstable.url = "github:nixos/nixpkgs?ref=nixos-unstable";
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-25.05";
    home-manager = {
      url = "github:nix-community/home-manager/release-25.05";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    home-manager-unstable = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs-unstable";
    };
    auto-cpufreq = {
      url = "github:AdnanHodzic/auto-cpufreq";
      inputs.nixpkgs.follows = "nixpkgs-unstable";
    };
    nixpkgs-raspi.url = "github:nvmd/nixpkgs/modules-with-keys-25.05";
    nixos-raspberrypi = {
      url = "github:nvmd/nixos-raspberrypi/main";
      inputs.nixpkgs.follows = "nixpkgs-raspi";
    };
    disko = {
      url = "github:nix-community/disko";
      inputs.nixpkgs.follows = "nixpkgs-unstable";
    };
    sops-nix = {
      url = "github:Mic92/sops-nix";
      inputs.nixpkgs.follows = "nixpkgs-unstable";
    };
    nixos-images = {
      url = "github:nvmd/nixos-images/sdimage-installer";
      inputs.nixos-stable.follows = "nixpkgs";
      inputs.nixos-unstable.follows = "nixpkgs";
    };
    treefmt-nix = {
      url = "github:numtide/treefmt-nix";
    };
    nixos-hardware.url = "github:nixos/nixos-hardware/master";
  };

  nixConfig = {
    extra-substituters = [ "https://nixos-raspberrypi.cachix.org" ];
    extra-trusted-public-keys = [
      "nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
    ];
  };

  outputs =
    {
      self,
      nixpkgs,
      nixpkgs-unstable,
      home-manager,
      home-manager-unstable,
      auto-cpufreq,
      nixpkgs-raspi,
      nixos-raspberrypi,
      disko,
      sops-nix,
      nixos-images,
      treefmt-nix,
      nixos-hardware,
    }@inputs:
    {
      # ...

      nixosConfigurations = {
        # ...
        maximusZoneAprilL = nixos-raspberrypi.lib.nixosSystemFull {
          specialArgs = inputs;
          modules = [
            # Disk configuration
            disko.nixosModules.disko
            ./maximus-zone-april-l
            (import ./common/nix.nix {
              trustedUsers = [
                "root"
                "nixos"
              ];
            })
          ];
        };
      };
    };
}

And the Disko config I am trying to apply is

{ ... }:

let
  poolName = "tank1";
in
{
  disko.devices = {
    disk = {
      data1 = {
        type = "disk";
        content = {
          type = "gpt";
          partitions = {
            zfs = {
              size = "100%";
              content = {
                type = "zfs";
                pool = "${poolName}";
              };
            };
          };
        };
      };
    };
    zpool = {
      "${poolName}" = {
        type = "zpool";
        mode = "mirror";
        rootFsOptions = {
          compression = "zstd";
          "com.sun:auto-snapshot" = "true";
        };
        postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^${poolName}@blank$' || zfs snapshot ${poolName}@blank";

        datasets = {
          # From NixOS wiki: On ZFS, the performance will deteriorate significantly when more than 80% of the available space is used.
          # To avoid this, reserve disk space beforehand.
          reserved = {
            type = "zfs_fs";
            mountpoint = "/${poolName}/reserved";
            options = {
              quota = "10G";
            };
          };
          encrypted = {
            type = "zfs_fs";
            mountpoint = "/${poolName}";
            options = {
              encryption = "aes-256-gcm";
              keyformat = "passphrase";
              keylocation = "file:///tmp/secret.key";
            };
            # use this to read the key during boot
            postCreateHook = ''
              zfs set keylocation="prompt" "${poolName}/encrypted";
            '';
          };
        };
      };
    };
  };
}

Can you help me? What am I missing?

The NixOS wiki mentions something about ZFS not being part of all linux kernels. Could this be the issue?

I have solved it. The issue was - as so often - simple: I had both the SD card and NVMe drive attached, but didn’t change the default boot order, so the PI was booting from the card. After removing the card and nixos-rebuild switch’ing again, ZFS was loaded.