nixOS not showing up in grub

I am struggling to move nix from the systems bootloader to grub. I have gotten as far as the NixOS-boot-efi option (appears when mashing f12, in the same menu as booting from a USB), loading up grub, but nix doesn’t show up there. I need to use systemd-bootloader (which shows up as “linux-boot-manager”) to load nixos.

I am completely new to nixOS, though not to Linux in general. When I run sudo nixos-rebuild switch, it runs, saying that it is updating the grub2 entries, but when I reboot, nothing changes.

I will reply with a copy of my config after I’ve posted this, the only part I’ve changed is the bootloader section.

#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.
  
  #uncomment the following lines for a systemd bootloader
  #boot.loader.systemd-boot.enable = true;
  #boot.loader.efi.canTouchEfiVariables = true;

  #an attempt at getting grub to work
   boot.loader = {
     efi = {
        #canTouchEfiVariables = true;
        #efiSysMountPoint = "/boot/efi"; # ← use the same mount point here.
     };
      grub = {
        enable = true;
        efiSupport = true;
        efiInstallAsRemovable = true; # in case canTouchEfiVariables doesn't work for your system
        device = "nodev";
      };
      systemd-boot = {
       enable = false;
      };
   
};

  # 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;

  # Set your time zone.
  time.timeZone = "Europe/London";

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

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

  # Enable the X11 windowing system.
  services.xserver.enable = true;

  # Enable the GNOME Desktop Environment.
  services.xserver.displayManager.gdm.enable = true;
  services.xserver.desktopManager.gnome.enable = true;

  # Configure keymap in X11
  services.xserver.xkb = {
    layout = "gb";
    variant = "";
  };

  # Configure console keymap
  console.keyMap = "uk";

  # Enable CUPS to print documents.
  services.printing.enable = true;

  # Enable sound with pipewire.
  services.pulseaudio.enable = false;
  security.rtkit.enable = true;
  services.pipewire = {
    enable = true;
    alsa.enable = true;
    alsa.support32Bit = true;
    pulse.enable = true;
    # If you want to use JACK applications, uncomment this
    #jack.enable = true;

    # use the example session manager (no others are packaged yet so this is enabled by default,
    # no need to redefine it in your config for now)
    #media-session.enable = true;
  };

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

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

  # Install firefox.
  programs.firefox.enable = true;

  # 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?

}

nixos-rebuild doesn’t normally reinstall the bootloader, just updates the menu entries, so if you change the configured bootloader you need to run nixos-rebuild --install-bootloader switch to trigger that to happen.

1 Like

It also doesn’t uninstall the boot loader at all, so the systemd-boot installation is still kicking around. Its files probably ought to be deleted, especially since it takes the $ESP/EFI/BOOT/BOOTX64.EFI fallback loader path. Some motherboards always prefer this path, and some motherboards always ignore it if there are any actual EFI boot entries pointing at the drive.

1 Like

He’s set boot.loader.grub.efiInstallAsRemovable = true;, so it should overwrite the fallback path, in this case. But yes, in general, uninstalling the previous bootloader is something you have to do manually, and even here, the other related files will need manual removal.

Also, nitpick: You don’t need to set boot.loader.systemd-boot.enable = false;. Enabling grub will do that automatically. There’s no harm in it beyond it being unnecessary, though.

1 Like

I should probably clarify some things, I ran sudo nixos-rebuild --install-bootloader switch, nothing changed.

My default bootloader currently is grub, nixOS just isn’t showing up on it.

If possible, I would like to keep systems boot around, just as a fallback if I mess something up and grub breaks.

(Also, I only set boot.loader.systemd.enable to false because of a random thread I found, and by that point I was willing to try anything :sweat_smile:)

What OS is managing that grub? Did you configure it to chainload to NixOS’ Grub? Have you tried making NixOS’ grub the default?

If didn’t realise that grub was owned by an OS, I am currently dual booting fedora, which uses grub by default, windows, and nixOS. If I were to guess, it’s probably owned by fedora. If nix were to own it, would that break fedora’s grub entries?

Edit: I also have no clue how to hand over ownership, since I didn’t know it existed, nor what a chain load is.

Nixos needs to write its own grub.cfg in order to update the menu entries for each new generation. It can’t share with another distro except by adding the other distro’s menu entries to an instance of grub installed and managed by nixos, or by chainloading between the bootloaders one direction or the other.

By default, yes, but you could add fedora’s entries to your nixos configuration. Same with windows. In fact, enabling boot.loader.grub.useOSProber would probably do so automatically, though I’d recommend switching to boot.loader.grub.extraEntries at some point, as running os-prober on every rebuild is slow.

If --install-bootloader didn’t seem to do anything, you probably didn’t configure the bootloader correctly. In particular, make sure boot.loader.efi.efiSysMountPoint is set correctly.

It sounds like you’ve got a few issues, most of which have been mentioned, but one I haven’t seen mentioned is that you do not have boot.loader.efi.canTouchEfiVariables = true; set anywhere, you have it commented out in two places. If you want nixos-rebuild --install-bootloader switch to register the NixOS GRUB install with your computers EFI firmware you need to enable this. I’m also not convinced that you set boot.loader.grub.efiInstallAsRemovable = true; intentionally, do you know why you have this enabled, as most computers do not need it.

If you weren’t installing GRUB as removable intentionally, I would recommend switching your boot.loader section entirely to the following. This will install GRUB for the NixOS system, use OSProber to detect the Fedora install and add it to the NixOS GRUB install, and then register the NixOS GRUB with your computers EFI firmware so it appears when you press F12 at boot.


boot.loader = {
  efi.canTouchEfiVariables = true;
  grub = {
    enable = true;
    efiSupport = true;
    device = "nodev";
    useOSProber = true;
  };
};

You don’t need boot.loader.efi.canTouchEfiVariables if you set boot.loader.grub.efiInstallAsRemoveable, so that shouldn’t be an issue. Though usually you only do the removeable install if you need it for some reason, yes.