Unable to nixos-rebuild switch/boot: FileNotFoundError

When I tried to switch to a new build of nixos configuration, it failed with the following error:

building the system configuration...
Traceback (most recent call last):
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 538, in <module>
    main()
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 521, in main
    install_bootloader(args)
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 454, in install_bootloader
    remove_old_entries(gens, entries)
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 346, in remove_old_entries
    os.unlink(disk_entry.path)
FileNotFoundError: [Errno 2] No such file or directory: '/boot/loader/entries/nixos-generation-1746-specialisation-alt.conf'
warning: error(s) occurred while switching to the new configuration

The build was successfully, but it could switch to the new build because it failed to remove some files in the boot directory. I checked the directory and the file was not there and I don’t have any specialisation named alt. (Only two specialisation alt-key and no-key).

It occurred only today probably because I had used Ctrl-C to abort the previous nixos-rebuild switch command. Ever since then, I couldn’t switch to any new configuration. I guess there’s some consistency issue, but I’m not able to clean it up (I already tried nix-collect-garbage but to no avail)

Any help would be greatly appreciated!

You can reinstall the bootloader with:

sudo nixos-rebuild --install-bootloader boot

The same error occurred with the --install-bootloader flag and nixos-rebuild boot:

building the system configuration...
Copied "/nix/store/0zmji8sw3jm1j4akllcwc6g7i8cilyza-systemd-256.2/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/systemd/systemd-bootx64.efi".
Copied "/nix/store/0zmji8sw3jm1j4akllcwc6g7i8cilyza-systemd-256.2/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/BOOT/BOOTX64.EFI".
⚠️ Mount point '/boot' which backs the random seed file is world accessible, which is a security hole! ⚠️
⚠️ Random seed file '/boot/loader/random-seed' is world accessible, which is a security hole! ⚠️
Random seed file /boot/loader/random-seed successfully refreshed (32 bytes).
Created EFI boot entry "Linux Boot Manager".
Traceback (most recent call last):
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 538, in <module>
    main()
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 521, in main
    install_bootloader(args)
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 454, in install_bootloader
    remove_old_entries(gens, entries)
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 346, in remove_old_entries
    os.unlink(disk_entry.path)
FileNotFoundError: [Errno 2] No such file or directory: '/boot/loader/entries/nixos-generation-1746-specialisation-alt.conf'
warning: error(s) occurred while switching to the new configuration

Well, it’s complaining that it can’t delete the file. I think it’d be pretty safe to just touch /boot/loader/entries/nixos-generation-1746-specialisation-alt.conf and run that again.

Possibly worth creating an issue upstream, though, the script should ideally be robust to this kind of thing.

Also you may want to make your /boot have a umask that prevents non-root users editing it if you get that output at runtime:

fileSystems."/boot".options = [ "umask=0077" ];
1 Like

It doesn’t work either. If I just touch that file I get the following error (which is expected):

Created EFI boot entry "Linux Boot Manager".
Traceback (most recent call last):
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 538, in <module>
    main()
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 521, in main
    install_bootloader(args)
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 453, in install_bootloader
    entries = scan_entries()
              ^^^^^^^^^^^^^^
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 209, in scan_entries
    entries.append(DiskEntry.from_path(path))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/5vmys3xpxgb50ywszfiysf4ca846bg6i-systemd-boot", line 96, in from_path
    assert "linux" in entry_map
           ^^^^^^^^^^^^^^^^^^^^
AssertionError
warning: error(s) occurred while switching to the new configuration

However, if I copy another config file in the same dir to /boot/loader/entries/nixos-generation-1746-specialisation-alt.conf, the same FileNotFound error occurred, an the file was gone after running the command. (It suggests that the file was deleted more than once)

Fair enough, I suppose it’s really bloody broken. Make a backup of your current boot directory, delete everything, try to install the bootloader? If that doesn’t work you can restore the old files.

This approach worked amazingly! Thanks for your suggestions!

I’m running into the error from the initial post. The file my rebuild can’t unlink is named:

/boot/loader/entries/nixos-generation-123-specialisation-no.conf

I use two specialisations on this machine: the default and one named no_vfio (GPU juggling for gaming). It looks like the script is truncating the specialisation name at any punctuation. The initial post has the script trying to delete a conf file for the alt specialisation, which doesn’t exist, but there is one named alt-key.

I took a look at the script on nixpkgs and this regex caught my attention:

r"^nixos.*-generation-([0-9]+)-specialisation-([a-zA-Z0-9]+).*\.conf$"

That’s not going to match our specialisations with hyphens or underscores in the names. I haven’t taken the time to understand what this program is doing, so I can’t say whether that’s the whole problem or a problem at all.

Are there supposed to be any restrictions on the names for specialisations?

2 Likes

I manually removed the conf files for the generations I had recently garbage collected and was able to proceed with a regular nixos-rebuild boot. So there is a workaround less exciting than clearing out the whole ESP.

I suspect this is happening to anyone who has a garbage-collected generation with punctuation in a specialisation name, and there are still files for it in /boot/loader/entries. The script wants to remove the conf file, but reconstructs an incorrect filename.

1 Like

Good sleuthing! If this is intended, the options for this should fail at build time, rather than the boot loader installation falling after garbage collection. More likely than not this is just an oversight - I can’t spot any issues regarding this upstream, mind filing one?