Multi boot with encryption... Grub broken

Hi everyone.

I have a laptop with:

  1. EFI parition 100mb
  2. NTFS windows partition
  3. OpenSUSE TW LUKS partition
  • Since it’s encrypted I have a separate unencrypted 1GB partition that is mounted as /boot, and /boot/efi is instead mounted on partition 1.

I wanted to install NixOs and I did:

  • Resize NTFS windows partition.
  • Created a 1GB partition mounted as /boot for Nixos
  • Mounted /boot/efi on partition 1
  • Created a 200gb partition LUKS encrypted mounted as /

Done everything trough the grafical installer.

Now grub is broken, I see only two voices: “Nixos” and “Firmware settigns”. My other os are not there. Also no option to switch generation. Only these two voices.

I saw online how to configure grub so here is what I did on my config file:

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Bootloader. THESE WERE ENABLED AFTER FIRST INSTALL
#  boot.loader.systemd-boot.enable = true;
#  boot.loader.efi.canTouchEfiVariables = true;

  # WHAT I ADDED: GRUB
  boot.loader = {
    efi.efiSysMountPoint = "/boot/efi";
    efi.canTouchEfiVariables = true;
    grub = {
      enable = true;
      device = "nodev";
      useOSProber = true;
      efiSupport = true;
    };

  };

  # Use latest kernel.
  boot.kernelPackages = pkgs.linuxPackages_latest;

  networking.hostName = "nixos"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;
  
  services.openssh.enable = true;
  services.openssh.ports = [22];
  services.openssh.settings.PasswordAuthentication = true;  
  services.openssh.settings.PermitRootLogin = "yes";  
  services.openssh.settings.AllowUsers = null;
  networking.firewall.allowedTCPPorts = [22];
  
  # Set your time zone.
  time.timeZone = "Europe/Rome";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "it_IT.UTF-8";
    LC_IDENTIFICATION = "it_IT.UTF-8";
    LC_MEASUREMENT = "it_IT.UTF-8";
    LC_MONETARY = "it_IT.UTF-8";
    LC_NAME = "it_IT.UTF-8";
    LC_NUMERIC = "it_IT.UTF-8";
    LC_PAPER = "it_IT.UTF-8";
    LC_TELEPHONE = "it_IT.UTF-8";
    LC_TIME = "it_IT.UTF-8";
  };

  # Configure keymap in X11
  services.xserver.xkb = {
    layout = "it";
    variant = "";
  };
  
  security.polkit.enable = true;
  # Configure console keymap
  console.keyMap = "it";

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.ironhak = {
    isNormalUser = true;
    description = "ironhak
    extraGroups = [ "networkmanager" "wheel" ];
    packages = with pkgs; [];
  };

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
  #  vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
  #  wget
  ];

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  # services.openssh.enable = true;

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "25.05"; # Did you read the comment?

}

Also, if its needed, here’s the hardware config:

# Do not modify this file!  It was generated by ‘nixos-generate-config’
# and may be overwritten by future invocations.  Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:

{
  imports =
    [ (modulesPath + "/installer/scan/not-detected.nix")
    ];

  boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
  boot.initrd.kernelModules = [ ];
  boot.kernelModules = [ "kvm-intel" ];
  boot.extraModulePackages = [ ];

  fileSystems."/" =
    { device = "/dev/disk/by-uuid/aee0fdcf-844d-4837-b5fb-5a022c3b4bfb";
      fsType = "ext4";
    };

  boot.initrd.luks.devices."luks-9c06c055-6a8c-436e-9a5c-4557bf4e6e23".device = "/dev/disk/by-uuid/9c06c055-6a8c-436e-9a5c-4557bf4e6e23";

  fileSystems."/boot" =
    { device = "/dev/disk/by-uuid/9C44-F496";
      fsType = "vfat";
      options = [ "fmask=0077" "dmask=0077" ];
    };

  swapDevices = [ ];

  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
  # (the default) this is the recommended approach. When using systemd-networkd it's
  # still possible to use this option, but it's recommended to use it in conjunction
  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
  networking.useDHCP = lib.mkDefault true;
  # networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
  # networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
  # networking.interfaces.wwp0s20f0u7.useDHCP = lib.mkDefault true;

  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
  hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

Can someone help please?

Edit, if it can help, when I rebuild I get this:

building Nix...
building the system configuration...
updating GRUB 2 menu...
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
lsblk: /dev/mapper/no*[0-9]: not a block device
lsblk: /dev/mapper/block*[0-9]: not a block device
lsblk: /dev/mapper/devices*[0-9]: not a block device
lsblk: /dev/mapper/found*[0-9]: not a block device
activating the configuration...
setting up /etc...
reloading user units for ironhak...
restarting sysinit-reactivation.target
the following new units were started: NetworkManager-dispatcher.service
Done. The new configuration is /nix/store/688js59cs2z2qwxzrpsh7r6s15f8l6rc-nixos-system-nixos-25.05.803471.4792576cb003

That’s not grub, that’s systemd-boot.

That’s because systemd-boot only auto-detects Windows by default. Which I’m surprised it didn’t do. For anything it doesn’t detect, it’s easy enough to add boot.loader.systemd-boot.extraEntries to manually chainload into the other OS’s boot loader.

If you want to switch to grub for the sake of OS-prober, your configuration looks correct to me, but there’s a catch. It won’t uninstall systemd-boot automatically. You’ll need to use efibootmgr to remove the UEFI boot entry that’s pointing at systemd-boot, you’ll need to delete systemd-boot’s $ESP/EFI/BOOT/BOOTX64.EFI fallback loader (which is likely overriding the newly installed grub) and the regular $ESP/EFI/systemd/systemd-bootx64.efi loader, and you’ll want to delete the $ESP/EFI/nixos and $ESP/loader directories that house NixOS’s systemd-boot files like the kernel and loader.conf.

I’ve deleted all these folders and now I can’t boot anymore. The laptop just stay stuck at manufacturer logo… If I try to boot on “opensuse-secureboot” or “window boot manger” from bios, the laptop restart and goes straight to bios…

You should be able to use the UEFI boot menu to select NixOS / grub. If not, boot the installer again, mount your file systems manually at /mnt and /mnt/boot/efi and run nixos-install.

Thanks but why should I install the os again?

Also the partition is encrypted. And thus there is a separate /boot partition and the /boot/efi is mounted on a another partition.

What you’re really trying to do is get NixOS to reconfigure its boot loader. Technically you don’t need to use nixos-install for this (nixos-enter followed by nixos-rebuild boot should work as well, it just has some funky output that looks like errors but isn’t). But nixos-install is totally fine as well; you can nixos-install the same configuration twice and the second time will reuse the existing installation and produce the same results.

You’re right, sorry. The point is to mount your file systems at /mnt however they would normally be mounted at /, of course including your /boot and /boot/efi partitions

Thanks… But I don’t really know how to proceed on this…

Do you maybe have any tips on how I can do? Thanks and sorry for bothering

I already told you. Boot the nixos ISO, mount your file systems under /mnt, /mnt/boot, and /mnt/boot/efi, and run nixos-install.

Ok.

# lsblk -f
NAME FSTYPE FSVER LABEL                        UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
loop0
     squash 4.0                                                                           0   100% /nix/.ro-store
sda  iso966 Jolie nixos-graphical-25.05-x86_64 1980-01-01-00-00-00-00                              
├─sda1
│    iso966 Jolie nixos-graphical-25.05-x86_64 1980-01-01-00-00-00-00                     0   100% /iso
└─sda2
     vfat   FAT12 EFIBOOT                      1234-5678                                           
nvme0n1
│                                                                                                  
├─nvme0n1p1
│                                                                                                  
├─nvme0n1p2
│                                                                                                  
├─nvme0n1p3
│    ntfs                                      3E2E6C902E6C434F                                    
├─nvme0n1p4
│    ntfs                                      A4F0BB1FF0BAF720                                    
├─nvme0n1p5
│    crypto 2                                  1e54c821-d9f7-49ad-afd5-af1008b77544                
├─nvme0n1p6
│    swap   1                                  810387f5-e151-46a8-9b34-4eb251300735                
├─nvme0n1p7
│    vfat   FAT32                              FA99-DC28                                           
├─nvme0n1p8
│    vfat   FAT32 NIXOS BOOT                   9C44-F496                                           
└─nvme0n1p9
     crypto 2                                  9c06c055-6a8c-436e-9a5c-4557bf4e6e23

[root@nixos:~]# sudo parted -l
Model: SKHynix_HFS512GDE9X081N (nvme)
Disk /dev/nvme0n1: 512GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End    Size    File system     Name                          Flags
 1      1049kB  106MB  105MB                   EFI system partition          bios_grub, no_automount
 2      106MB   123MB  16.8MB                  Microsoft reserved partition  msftres, no_automount
 3      123MB   120GB  120GB   ntfs            Basic data partition          msftdata
 8      120GB   121GB  1049MB  fat32                                         boot, esp
 9      121GB   272GB  151GB
 7      272GB   273GB  1074MB  fat32                                         boot, esp
 5      273GB   509GB  236GB
 6      509GB   512GB  2147MB  linux-swap(v1)                                swap
 4      512GB   512GB  534MB   ntfs                                          hidden, diag, no_automount

I unlock the encryption on nvme0n1p9 (nixos root) and mount it under /mnt.

sudo cryptsetup luksOpen /dev/nvme0n1p9 my_nixos_encr
sudo mount /dev/mapper/my_nixos_encr /mnt

Now I mount nvme0n1p8 (NixOS boot partition) under /mnt/boot:

sudo mount /dev/nvme0n1p8 /mnt/boot

Now I mount the BIOS boot partition nvme0n1p1 to mnt/boot/efi:

[root@nixos:~]# sudo mount /dev/nvme0n1p1 /mnt/boot/efi
mount: /mnt/boot/efi: wrong fs type, bad option, bad superblock on /dev/nvme0n1p1, missing codepage or helper program, or other error.
       dmesg(1) may have more information after failed mount system call.

If I try to nixos-install anyway:

copying channel...
building the configuration in /mnt/etc/nixos/configuration.nix...
/nix/store/8vk22fygfharv16w0q31sg334wx3m5iy-nixos-system-nixos-25.05.803471.4792576cb003
installing the boot loader...
setting up /etc...
updating GRUB 2 menu...
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
ERROR: mkdir /var/lock/dmraid
grub-probe: error: cannot find a GRUB drive for /dev/sda1.  Check your device.map.
installing the GRUB 2 boot loader into /boot/efi...
Installing for x86_64-efi platform.
modprobe: can't change directory to '/lib/modules': No such file or directory
Installation finished. No error reported.
setting up /etc...
setting up /etc...
setting root password...
New password: 
Retype new password: 
passwd: password updated successfully
installation finished!

And the system is still un-bootable.

According to your lsblk output, nvme0n1p1 is not your ESP, or you wiped it or something; it doesn’t have a file system on it. Are you sure you didn’t mount a different partition as your ESP when you initially installed NixOS? If you run fdisk -l /dev/nvme0n1, which one(s) are of type EFI System?

The system is still unbootable because you didn’t have the ESP mounted when you did the nixos-install

# fdisk -l /dev/nvme0n1
Disk /dev/nvme0n1: 476.94 GiB, 512110190592 bytes, 1000215216 sectors
Disk model: SKHynix_HFS512GDE9X081N                 
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: D98A2F94-9AB4-4DCF-9840-09C6906D738E

Device             Start        End   Sectors   Size Type
/dev/nvme0n1p1      2048     206847    204800   100M BIOS boot
/dev/nvme0n1p2    206848     239615     32768    16M Microsoft reserved
/dev/nvme0n1p3    239616  234016767 233777152 111.5G Microsoft basic dat
/dev/nvme0n1p4 999170048 1000212479   1042432   509M Windows recovery en
/dev/nvme0n1p5 533647360  994973695 461326336   220G Linux filesystem
/dev/nvme0n1p6 994975744  999170047   4194304     2G Linux swap
/dev/nvme0n1p7 531550208  533647359   2097152     1G EFI System
/dev/nvme0n1p8 234016768  236064767   2048000  1000M EFI System
/dev/nvme0n1p9 236064768  531550207 295485440 140.9G Linux filesystem

Partition table entries are not in disk order.

I didn’t think I wiped it… Unless I selected it from the nixos gui installer as mount point of /boot/efi and I didn’t unchecked the option to format the partition… Honestly I’m not sure, I’m 99% sure I installed correctly and without formatting the BIOS boot partition… But not sure.

What can I do now?

Oh, I glossed over your parted output before. I think I see what got screwed up:

You have a 100M partition named “EFI system partition”, but it doesn’t have the esp flag like two of those below it do. I think what happened is you told the GUI installer to create a new ESP for /boot/efi, also create another new ESP for /boot, and then set some grub flags on the existing ESP. I don’t know why the original ESP would have gotten wiped and no longer has a file system; maybe at one point you tried setting boot.loader.grub.device = "/dev/nvme0n1p1"; or something?

Regardless, you’ve now got three partitions, but you only need 2. One should be the ESP, formatted with FAT32 and with the partition type “EFI System”. The other should be your /boot partition, formatted with something Grub can understand. Really you only need one partition, and /boot can just also be your ESP and generally this is how I recommend setting it up. But 100M is not large enough for that so you have to either use a different larger partition that way as your ESP or set it up in this split fashion.

Once you’ve got your partitions set up in one of those two ways (either a single /boot partition that is also your ESP, or separate /boot and ESP at /boot/efi), get all this mounted in the ISO under /mnt. Then you need to make sure your configuration.nix has boot.loader.efi.efiSysMountPoint set to the path the ESP is mounted at under /mnt, so either "/boot/efi" or "/boot" depending on which way you laid it out. Regen your hardware-configuration.nix with nixos-generate-config --root /mnt and then nixos-install.

Yes, I did that before using “nodev” as suggested on wiki.

Anyway I have 3 partitions because:

  • One 100mb partition that is the EFI partition (used for windows and bootloader)
  • One 1GB partition that contains the /boot (kernel) of OpenSUSE Tumblweed (because it’s encrypted)
  • One 1GB partition that contains the /boot (kernel) of NixOS (because root partition is encrypted)

So, maybe I did not understood what you’re saying… But at this point I don’t understand what to do

Oh, I see, one of those is for OpenSUSE.

Anyway, I think your biggest issue right now is that nvme0n1p1 does not have a file system on it, and is not marked as partition type EFI System. I don’t know why that got wiped, but I think the fact that it has been means that you’ve lost all your boot loaders.

You should mount your NixOS root file system at /mnt, your NixOS /boot file system at /mnt/boot, and you need to fix your ESP and then mount it at /mnt/boot/efi. Now, I’m not sure how you want to go about fixing your ESP. If it’s possible to recover the file system it used to have, I don’t know how to do it. The alternative is to just reformat it with FAT32 anew, and figure out how to fix Windows and OpenSUSE later (they should have both had boot loaders on the ESP).

Once you’ve got the file systems mounted, run nixos-generate-config --root /mnt to make sure hardware-configuration.nix is up to date for how your file systems should be set up. Then run nixos-install.

I’ve formatted nvme0n1p1 to FAT32 as suggested.

Then:

sudo mount /dev/nvme0n1p1 /mnt/boot/efi

worked.

I’ve run nixos-generate-config --root /mnt and then nixos-install, here’s the isntallation output:

copying channel...
building the configuration in /mnt/etc/nixos/configuration.nix...
these 7 derivations will be built:
  /nix/store/31100sqilc18gbfi590a4vb1rrf6jvrs-etc-fstab.drv
  /nix/store/58n5vwiqcqn11lw8s1pb3603m8x0djzs-stage-1-init.sh.drv
  /nix/store/kll6vj2qixwkyl9rrnrvr925cibxdc6n-closure-info.drv
  /nix/store/kf3yfvf6g74zgg5mr9bls6809hi2avfh-initrd-linux-6.15.1.drv
  /nix/store/vr54nbaqkl67b1g1j87yxm4a0ail5b05-boot.json.drv
  /nix/store/yzfmm4cjg6rk7ksl0v8jhvgjv6rcahbh-etc.drv
  /nix/store/fc5mr0wg2l8jmr6nrwb65bd21nfax60d-nixos-system-nixos-25.05.803471.4792576cb003.drv
building '/nix/store/31100sqilc18gbfi590a4vb1rrf6jvrs-etc-fstab.drv'...
building '/nix/store/58n5vwiqcqn11lw8s1pb3603m8x0djzs-stage-1-init.sh.drv'...
building '/nix/store/yzfmm4cjg6rk7ksl0v8jhvgjv6rcahbh-etc.drv'...
Running phase: patchPhase
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: configurePhase
no configure script, doing nothing
Running phase: buildPhase
Running phase: checkPhase
Running phase: installPhase
no Makefile or custom installPhase, doing nothing
checking syntax
Running phase: fixupPhase
shrinking RPATHs of ELF executables and libraries in /nix/store/ahqw0jbbvxsi613d3h7gwhjw2ilf1yzf-stage-1-init.sh
checking for references to /build/ in /nix/store/ahqw0jbbvxsi613d3h7gwhjw2ilf1yzf-stage-1-init.sh...
patching script interpreter paths in /nix/store/ahqw0jbbvxsi613d3h7gwhjw2ilf1yzf-stage-1-init.sh
building '/nix/store/kll6vj2qixwkyl9rrnrvr925cibxdc6n-closure-info.drv'...
structuredAttrs is enabled
building '/nix/store/kf3yfvf6g74zgg5mr9bls6809hi2avfh-initrd-linux-6.15.1.drv'...
building '/nix/store/vr54nbaqkl67b1g1j87yxm4a0ail5b05-boot.json.drv'...
building '/nix/store/fc5mr0wg2l8jmr6nrwb65bd21nfax60d-nixos-system-nixos-25.05.803471.4792576cb003.drv'...
/nix/store/56jb0ir4pzpzh1kfsrsz0zvzv360mmam-nixos-system-nixos-25.05.803471.4792576cb003
installing the boot loader...
setting up /etc...
updating GRUB 2 menu...
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
ERROR: mkdir /var/lock/dmraid
grub-probe: error: cannot find a GRUB drive for /dev/sda1.  Check your device.map.
installing the GRUB 2 boot loader into /boot/efi...
Installing for x86_64-efi platform.
modprobe: can't change directory to '/lib/modules': No such file or directory
Installation finished. No error reported.
setting up /etc...
setting up /etc...
setting root password...
New password: 
Retype new password: 
passwd: password updated successfully
installation finished!

It worked!!!

I have grub and I see all generations! Thanks so much my friend.

Now, the fun part will be to find a way to repair bootloaders

1 Like