Windows 11 GRUB entry doesn't show up dual-booting

I have Windows 11 installed and just recently switched over to Neon and I’m lovin’ it. I can’t seem to get a Windows 11 menuentry on Grub.

Windows 11 works, I can use the BIOS to boot directly to the “Windows boot loader”… but for the life of me, I can’t get grub to display Windows 11 on the boot menu.

The os-prober in the grub.cfg is disabled, as, I’d like a static entry on the grub boot menu.

Hoping the community has some guidance for me.

Here is the outputs for review:

sudo os-prober
/dev/nvme0n1p1@/EFI/Microsoft/Boot/bootmgfw.efi:Windows Boot Manager:Windows:efi
sudo grub-mkconfig -o /boot/grub/grub.cfg

Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99_breeze-grub.cfg'
Generating grub configuration file ...
Found theme: /boot/grub/themes/breeze/theme.txt
Found linux image: /boot/vmlinuz-6.11.0-25-generic
Found initrd image: /boot/initrd.img-6.11.0-25-generic
Found memtest86+ 64bit EFI image: /boot/memtest86+x64.efi
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
Adding boot menu entry for UEFI Firmware Settings ...
done
efibootmgr -u
BootCurrent: 0003
Timeout: 2 seconds
BootOrder: 0003,0000,001A,001B,001C,001D,001E,001F,0020,0021,0022,0002
Boot0000* Windows Boot Manager  HD(1,GPT,1a0d296c-5032-4bef-a407-93ca3ac5ec0f,0x800,0xfa000)/File(\EFI\Microsoft\Boot\bootmgfw.efi)䥗䑎坏S
Boot0002* Linux-Firmware-Updater        HD(1,GPT,5f263d2c-a7c9-4004-8248-2ef072ecda02,0x800,0x32000)/File(\EFI\linuxmint\shimx64.efi) File(.\fwupdx64.efi)
Boot0003* KDE neon 6.3  HD(1,GPT,1a0d296c-5032-4bef-a407-93ca3ac5ec0f,0x800,0xfa000)/File(\EFI\kde\shimx64.efi)
Boot0010  Setup FvFile(721c8b66-426c-4e86-8e99-3457c46ab0b9)
Boot0011  Boot Menu     FvFile(126a762d-5758-4fca-8531-201a7f57f850)
Boot0012  Diagnostic Splash Screen      FvFile(a7d8d9a6-6ab0-4aeb-ad9d-163e59a7a380)
Boot0013  Lenovo Diagnostics    FvFile(3f7e615b-0d45-4f80-88dc-26b234958560)
Boot0014  Asset Information     FvFile(da465b87-a26f-4c12-b78a-0361428fa026)
Boot0015  Regulatory Information        FvFile(478c92a0-2622-42b7-a65d-5894169e4d24)
Boot0016  ThinkShield secure wipe       FvFile(3593a0d5-bd52-43a0-808e-cbff5ece2477)
Boot0017  Startup Interrupt Menu        FvFile(f46ee6f4-4785-43a3-923d-7f786c3c8479)
Boot0018  Rescue and Recovery   FvFile(665d3f60-ad3e-4cad-8e26-db46eee9f1b5)
Boot0019  MEBx Hot Key  FvFile(ac6fd56a-3d41-4efd-a1b9-870293811a28)
Boot001A* USB CD        VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,86701296aa5a7848b66cd49dd3ba6a55)
Boot001B* USB FDD       VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,6ff015a28830b543a8b8641009461e49)
Boot001C* NVMe0 VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,001c199932d94c4eae9aa0b6e98eb8a400)
Boot001D* USB HDD       VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,33e821aaaf33bc4789bd419f88c50803)
Boot001E* PXE BOOT      VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,78a84aaf2b2afc4ea79cf5cc8f3d3803)
Boot001F* LENOVO CLOUD  VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,ad38ccbbf7edf04d959cf42aa74d3650)/Uri(https://download.lenovo.com/pccbbs/cdeploy/efi/boot.efi)
Boot0020* ON-PREMISE    VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,ad38ccbbf7edf04d959cf42aa74d3650)/Uri()
Boot0021  Other CD      VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a35400)
Boot0022  Other HDD     VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f600)
Boot0023* IDER BOOT CDROM       PciRoot(0x0)/Pci(0x14,0x0)/USB(11,1)
Boot0024* IDER BOOT Floppy      PciRoot(0x0)/Pci(0x14,0x0)/USB(11,0)
Boot0025* ATA HDD       VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,91af625956449f41a7b91f4f892ab0f6)
Boot0026* ATAPI CD      VenMsg(bc7838d2-0f82-4d60-8316-c068ee79d25b,aea2090adfde214e8b3a5e471856a354)
lsblk -o name,partuuid

NAME        PARTUUID
loop0       
loop1       
loop2       
loop3       
loop4       
loop5       
loop6       
loop7       
loop8       
nvme0n1     
├─nvme0n1p1 1a0d296c-5032-4bef-a407-93ca3ac5ec0f
├─nvme0n1p2 a2529073-fa15-43be-bcdd-3dc8ebe60e74
├─nvme0n1p3 c98b122c-69c6-43dd-8e5f-7dfaa9e73d5e
├─nvme0n1p4 afcdc7ee-d8bf-411c-92ba-1b9853e39329
├─nvme0n1p5 1d214fb0-1d99-4eab-bb96-d50cd88b58e2
├─nvme0n1p6 1f2f09e8-49b4-4c1e-aeac-3d9a10ed1c68
└─nvme0n1p7 f3680a6a-fd72-4ae1-8c4b-d0c0336bc259
sudo grub-mkconfig 2>/dev/null
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
  set have_grubenv=true
  load_env
fi
if [ "${initrdfail}" = 2 ]; then
   set initrdfail=
elif [ "${initrdfail}" = 1 ]; then
   set next_entry="${prev_entry}"
   set prev_entry=
   save_env prev_entry
   if [ "${next_entry}" ]; then
      set initrdfail=2
   fi
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="0"
fi

if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}
function initrdfail {
    if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
      if [ -z "${initrdfail}" ]; then
        set initrdfail=1
        if [ -n "${boot_once}" ]; then
          set prev_entry="${default}"
          save_env prev_entry
        fi
      fi
      save_env initrdfail
    fi; fi
}
function recordfail {
  set recordfail=1
  if [ -n "${have_grubenv}" ]; then if [ -z "${boot_once}" ]; then save_env recordfail; fi; fi
}
function load_video {
  if [ x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

if [ x$feature_default_font_path = xy ] ; then
   font=unicode
else
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root 47a79a72-54fa-431f-85ca-2fdce4ed7a80
    font="/usr/share/grub/unicode.pf2"
fi

if loadfont $font ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=en_CA
  insmod gettext
fi
terminal_output gfxterm
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root 47a79a72-54fa-431f-85ca-2fdce4ed7a80
insmod gfxmenu
loadfont ($root)/boot/grub/themes/breeze/unifont-bold-16.pf2
loadfont ($root)/boot/grub/themes/breeze/unifont-regular-14.pf2
loadfont ($root)/boot/grub/themes/breeze/unifont-regular-16.pf2
insmod png
set theme=($root)/boot/grub/themes/breeze/theme.txt
export theme
if [ "${recordfail}" = 1 ] ; then
  set timeout=30
else
  if [ x$feature_timeout_style = xy ] ; then
    set timeout_style=menu
    set timeout=10
  # Fallback normal timeout code in case the timeout_style feature is
  # unavailable.
  else
    set timeout=10
  fi
fi
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/05_debian_theme ###
set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue
### END /etc/grub.d/05_debian_theme ###

### BEGIN /etc/grub.d/10_linux ###
function gfxmode {
        set gfxpayload="${1}"
        if [ "${1}" = "keep" ]; then
                set vt_handoff=vt.handoff=7
        else
                set vt_handoff=
        fi
}
if [ "${recordfail}" != 1 ]; then
  if [ -e ${prefix}/gfxblacklist.txt ]; then
    if [ ${grub_platform} != pc ]; then
      set linux_gfx_mode=keep
    elif hwmatch ${prefix}/gfxblacklist.txt 3; then
      if [ ${match} = 0 ]; then
        set linux_gfx_mode=keep
      else
        set linux_gfx_mode=text
      fi
    else
      set linux_gfx_mode=text
    fi
  else
    set linux_gfx_mode=keep
  fi
else
  set linux_gfx_mode=text
fi
export linux_gfx_mode
menuentry 'KDE neon 6.3 GNU/Linux' --class kde --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-47a79a72-54fa-431f-85ca-2fdce4ed7a80' {
        recordfail
        load_video
        gfxmode $linux_gfx_mode
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root 47a79a72-54fa-431f-85ca-2fdce4ed7a80
        linux   /boot/vmlinuz-6.11.0-25-generic root=UUID=47a79a72-54fa-431f-85ca-2fdce4ed7a80 ro  quiet splash $vt_handoff
        initrd  /boot/initrd.img-6.11.0-25-generic
}
submenu 'Advanced options for KDE neon 6.3 GNU/Linux' $menuentry_id_option 'gnulinux-advanced-47a79a72-54fa-431f-85ca-2fdce4ed7a80' {
        menuentry 'KDE neon 6.3 GNU/Linux, with Linux 6.11.0-25-generic' --class kde --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.11.0-25-generic-advanced-47a79a72-54fa-431f-85ca-2fdce4ed7a80' {
                recordfail
                load_video
                gfxmode $linux_gfx_mode
                insmod gzio
                if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
                insmod part_gpt
                insmod ext2
                search --no-floppy --fs-uuid --set=root 47a79a72-54fa-431f-85ca-2fdce4ed7a80
                echo    'Loading Linux 6.11.0-25-generic ...'
                linux   /boot/vmlinuz-6.11.0-25-generic root=UUID=47a79a72-54fa-431f-85ca-2fdce4ed7a80 ro  quiet splash $vt_handoff
                echo    'Loading initial ramdisk ...'
                initrd  /boot/initrd.img-6.11.0-25-generic
        }
        menuentry 'KDE neon 6.3 GNU/Linux, with Linux 6.11.0-25-generic (recovery mode)' --class kde --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.11.0-25-generic-recovery-47a79a72-54fa-431f-85ca-2fdce4ed7a80' {
                recordfail
                load_video
                insmod gzio
                if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
                insmod part_gpt
                insmod ext2
                search --no-floppy --fs-uuid --set=root 47a79a72-54fa-431f-85ca-2fdce4ed7a80
                echo    'Loading Linux 6.11.0-25-generic ...'
                linux   /boot/vmlinuz-6.11.0-25-generic root=UUID=47a79a72-54fa-431f-85ca-2fdce4ed7a80 ro recovery nomodeset dis_ucode_ldr 
                echo    'Loading initial ramdisk ...'
                initrd  /boot/initrd.img-6.11.0-25-generic
        }
}

### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/10_linux_zfs ###
### END /etc/grub.d/10_linux_zfs ###

### BEGIN /etc/grub.d/20_linux_xen ###

### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/20_memtest86+ ###
menuentry "Memory test (memtest86+x64.efi)" --class memtest $menuentry_id_option 'memtest86+' {
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root 47a79a72-54fa-431f-85ca-2fdce4ed7a80
        linux    /boot/memtest86+x64.efi
}
menuentry 'Memory test (memtest86+x64.efi, serial console)' --class memtest $menuentry_id_option 'memtest86+-serial' {
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root 47a79a72-54fa-431f-85ca-2fdce4ed7a80
        linux   /boot/memtest86+x64.efi console=ttyS0,115200
}
### END /etc/grub.d/20_memtest86+ ###

### BEGIN /etc/grub.d/25_bli ###
if [ "$grub_platform" = "efi" ]; then
  insmod bli
fi
### END /etc/grub.d/25_bli ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/30_uefi-firmware ###
if [ "$grub_platform" = "efi" ]; then
        fwsetup --is-supported
        if [ "$?" = 0 ]; then
                menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
                        fwsetup
                }
        fi
fi
### END /etc/grub.d/30_uefi-firmware ###

### BEGIN /etc/grub.d/35_fwupd ###
### END /etc/grub.d/35_fwupd ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
#menuentry "Windows 11 Pro" {
#    search --fs-uuid 1a0d296c-5032-4bef-a407-93ca3ac5ec0ff --no-floppy --set=root 165E-2F74
#    chainloader (${root})/efi/EFI/Microsoft/Boot/bootmgfw.efi
menuentry 'Windows 11 Boot Manager (on /dev/nvme0n1p1)' {
        insmod part_gpt
        insmod fat
        search --no-floppy --fs-uuid 1a0d296c-5032-4bef-a407-93ca3ac5ec0ff --set=root 165E-2F74
        chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg
fi
### END /etc/grub.d/41_custom ###

Thank you!

I don’t get

Anyway, I’ve used this /boot/grub/custom.cfg with Windows 10

menuentry 'Windows' --class windows --class os  {
    insmod part_gpt
    insmod fat
    search --no-floppy --label --set=root SYSTEM
    chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}

You’ll likely to have to adjust the ESP label, and maybe the Windows 11 .efi file.

BTW, I didn’t use it for long, because running Windows in a qemu/kvm VM worked far better. (Windows 10 ran better in the VM than on bare metal, though that may have been because Windows badly needed a reinstall.)

if you let os_prober run does it find windows and add it to the grub menu?

you have to let it run at least once to get menu entry, then you can copy that to 40_custom to make it static

after that you can turn os_prober off again.

Grub won’t display Windows on this boot menu, when I add it to the 40_custom file, this is what it looks like after I added your menuentry.

I tired that…but let me try it again, I’ll report back.

So, I enable os_prober to run… then I run an update-grub… and it finds the Windows boot manager:

Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99_breeze-grub.cfg'
Generating grub configuration file ...
Found theme: /boot/grub/themes/breeze/theme.txt
Found linux image: /boot/vmlinuz-6.11.0-25-generic
Found initrd image: /boot/initrd.img-6.11.0-25-generic
Found memtest86+ 64bit EFI image: /boot/memtest86+x64.efi
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.
Found Windows Boot Manager on /dev/nvme0n1p1@/EFI/Microsoft/Boot/bootmgfw.efi
Adding boot menu entry for UEFI Firmware Settings ...
done

So, now, I’ll copy the entry from the 30_os-prober file to 40_custom

This is what the OS_prober found:

### BEGIN /etc/grub.d/30_os-prober ###
menuentry 'Windows Boot Manager (on /dev/nvme0n1p1)' --class windows --class os $menuentry_id_option 'osprober-efi-165E-2F74' {
        insmod part_gpt
        insmod fat
        search --no-floppy --fs-uuid --set=root 165E-2F74
        chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
set timeout_style=menu
if [ "${timeout}" = 0 ]; then
  set timeout=10
fi
### END /etc/grub.d/30_os-prober ###

I’ll add this to my 40_custom:

menuentry 'Windows Boot Manager (on /dev/nvme0n1p1)' --class windows --class os $menuentry_id_option 'osprober-efi-165E-2F74' {
        insmod part_gpt
        insmod fat
        search --no-floppy --fs-uuid --set=root 165E-2F74
        chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}

I’ll turn off the OS_prober as well,
Then I’ll run sudo update-grub

This is the output:

Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/99_breeze-grub.cfg'
Generating grub configuration file ...
Found theme: /boot/grub/themes/breeze/theme.txt
Found linux image: /boot/vmlinuz-6.11.0-25-generic
Found initrd image: /boot/initrd.img-6.11.0-25-generic
Found memtest86+ 64bit EFI image: /boot/memtest86+x64.efi
Warning: os-prober will not be executed to detect other bootable partitions.
Systems on them will not be added to the GRUB boot configuration.
Check GRUB_DISABLE_OS_PROBER documentation entry.
Adding boot menu entry for UEFI Firmware Settings ...
done

Doesn’t look promising…

even though the /boot/grub/grub.cfg show the windows menu entry:

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
#menuentry "Windows 11 Boot Manager (on /dev/nvme0n1p1)" {
#        insmod part_gpt
#        insmod fat
#        search --no-floppy --fs-uuid 1a0d296c-5032-4bef-a407-93ca3ac5ec0ff --set=root 165E-2F74
#        chainloader /EFI/Microsoft/Boot/bootmgfw.efi
#}
#menuentry "Windows" --class windows --class os {
#    search --fs-uuid --no-floppy --set=root 165E-2F74
#  chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
#}
#menuentry 'Windows' --class windows --class os  {
#    insmod part_gpt
#    insmod fat
#    search --no-floppy --label --set=root SYSTEM
#    chainloader /EFI/Microsoft/Boot/bootmgfw.efi
#}
menuentry 'Windows Boot Manager (on /dev/nvme0n1p1)' --class windows --class os $menuentry_id_option 'osprober-efi-165E-2F74' {
        insmod part_gpt
        insmod fat
        search --no-floppy --fs-uuid --set=root 165E-2F74
        chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
#set timeout_style=menu
#if [ "${timeout}" = 0 ]; then
#  set timeout=10
#fi

### END /etc/grub.d/40_custom ###

Oh man! I rebooted…and I guess this time, I decided to SCROLL down to the bottom and keep going… and yes, the Windows Entry was there…but hidden. menu didn’t give me an indication that there were more entries that I couldn’t see (ie a scroll bar)…but it WAS there and it WORKS. Windows boots with the OS_prober entry and with my manual entry.

I will go count the number of hairs I pulled out with frustration.

Thank you both @jlittle and @skyfishgoo for your help!

after enabling os_prober and running update-grub, you only need the menu entry from the /boot/grub/grub.config file that is generated by the scripts.

just copy and paste that one menu entry for windows… this is all that my 40_custom contains

menuentry 'Windows 10 (on disk M.2_1)' --class windows --class os $menuentry_id_option 'osprober-efi-9236-3ABB' {
	insmod part_gpt
	insmod fat
	search --no-floppy --fs-uuid --set=root 9236-3ABB
	chainloader /efi/Microsoft/Boot/bootmgfw.efi
}

if you want this entry to appear in a different place in the grub menu, just change the prefix number on the file from 40 to some lower number… the scripts are executed in numerical order to populate the grub menu.

remember to cancel os_prober and run update-grub again to turn it off, otherwise you will have two windows menu entries.

also remember that this windows menu entry is now manual and will no longer update if you change anything about your windows install.