The OpenPXE iPXE menu is displayed normally and keyboard navigation works:
Up / Down
Home / End
Page Up / Page Down
However, the highlighted item cannot be selected.
Enter does not activate the highlighted item.
The main menu's x shortcut (item --key x exit) also does not activate Exit.
Instead, pressing Enter or x moves the selection back to the default Queued Deployment item.
The same behavior occurs on both the VM and physical laptop.
Reproduction
The generated main menu contains:
menu OpenPXE - network boot menu
item local Boot from Local HDD
item linux Linux Installers >
item tools Tools >
item queue Queued Deployment (join queue)
item --key x exit Exit iPXE
choose --default queue --timeout 600000 target || goto menu
The menu renders correctly, but choose never appears to commit the selected item.
and Debian 13 successfully boots into the installer.
This confirms that PXE, TFTP, HTTP scripting, OpenPXE ISO handling, and the generated boot scripts are working.
The problem appears to be specifically with interactive menu selection/input.
Request
Could you check the x86_64 UEFI snponly.efi / bundled iPXE input configuration and menu-selection behavior in v0.8.1?
I can test a patched snponly.efi or development build if useful.
## Environment
* OpenPXE **v0.8.1**
* x86_64 UEFI
* OpenPXE running in Docker
* PXE clients tested:
* QEMU/KVM VM
* Physical x86_64 laptop
* Both clients show the same behavior
* OpenPXE serves `snponly.efi`
## Problem
The OpenPXE iPXE menu is displayed normally and keyboard navigation works:
* Up / Down
* Home / End
* Page Up / Page Down
However, **the highlighted item cannot be selected**.
* Enter does not activate the highlighted item.
* The main menu's `x` shortcut (`item --key x exit`) also does not activate Exit.
* Instead, pressing Enter or `x` moves the selection back to the default **Queued Deployment** item.
The same behavior occurs on both the VM and physical laptop.
## Reproduction
The generated main menu contains:
```ipxe
menu OpenPXE - network boot menu
item local Boot from Local HDD
item linux Linux Installers >
item tools Tools >
item queue Queued Deployment (join queue)
item --key x exit Exit iPXE
choose --default queue --timeout 600000 target || goto menu
```
The menu renders correctly, but `choose` never appears to commit the selected item.
## Important test
I can interrupt the boot with `Ctrl-B` and reach:
```text
iPXE>
```
From there:
```text
chain http://10.10.10.10:8069/boot/_linux_menu.ipxe
```
successfully opens the Linux installer menu.
I can then directly chain:
```text
chain http://10.10.10.10:8069/boot/debian-13-7-0-amd64-netinst-sanboot.ipxe
```
and **Debian 13 successfully boots into the installer**.
This confirms that PXE, TFTP, HTTP scripting, OpenPXE ISO handling, and the generated boot scripts are working.
The problem appears to be specifically with **interactive menu selection/input**.
## Request
Could you check the x86_64 UEFI `snponly.efi` / bundled iPXE input configuration and menu-selection behavior in v0.8.1?
I can test a patched `snponly.efi` or development build if useful.
Thanks for the detailed report — and especially for the Ctrl-B tests. Hand-chaining debian-13-7-0-amd64-netinst-sanboot.ipxe booting fine localised this to the menu scripts rather than the network, HTTP/TFTP or the .efi binaries.
Root cause was in the scripts OpenPXE generates, not in iPXE selection or your firmware. The dispatch lines looked like this:
iseq ${target} local && chain .../boot/_local.ipxe || goto menu
iseq ${target} linux && chain .../boot/_linux_menu.ipxe || goto menu
...
iseq ${target} exit && exit || goto menu
iPXE evaluates &&/|| strictly left to right (POSIX-shell style, src/core/exec.csystem()), so for A && B || C the C branch runs whenever A fails. With A = iseq ${target} <item>, that means every item except the first one skipped its own chain and ran goto menu immediately — redrawing the menu with --default queue highlighted, exactly what you saw. x failed the same way, which is why Exit behaved like Enter. Only local (the first line) was ever reachable.
Fixed on main (commit e80a66b, tagged v0.8.2 — the version bump is in Cargo.toml):
dispatch is now the canonical iPXE pattern — goto ${target} || goto menu followed by one :label block per item, so a non-matching item can't fall into a stray goto menu;
menu-to-menu transitions use chain --replace (the new menu replaces the old image), so x exits to the firmware from any submenu and Back/forward navigation doesn't pile up nested scripts;
boot entries recover to the menu themselves if a kernel/initrd fetch fails (needed once menus --replace);
plus a few nearby script bugs of the same class: the arch-label probe ended in || true (true isn't an iPXE command — non-x86_64/UEFI/arm64 pairs would abort before drawing the menu), Utilities→Back redrew Utilities instead of returning to Tools, prompt --timeout aborted NIC Info, and the empty-password check compared against a literal "" token (iPXE has no quoting).
There's a new menu_dispatch_tests suite that runs the generated scripts through a small interpreter mirroring iPXE's system()/process_script() semantics and asserts each item reaches its expected chain URL — the old lines fail it. cargo test --workspace is green.
No firmware rebuild needed — the snponly.efi/ipxe.efi assets are untouched; only the server-generated scripts changed. So a new 0.8.2 image (or a build from main) is enough on the server side.
If you can retest once you're on 0.8.2, that'd be great — particularly Enter on a Linux/Windows submenu item, x from the top menu, and b/Back from a submenu back to the main menu. If anything still misbehaves, the menu/entry script text you get from Ctrl-B chain would pinpoint it.
Thanks for the detailed report — and especially for the Ctrl-B tests. Hand-chaining `debian-13-7-0-amd64-netinst-sanboot.ipxe` booting fine localised this to the menu scripts rather than the network, HTTP/TFTP or the .efi binaries.
**Root cause** was in the scripts OpenPXE generates, not in iPXE selection or your firmware. The dispatch lines looked like this:
```
iseq ${target} local && chain .../boot/_local.ipxe || goto menu
iseq ${target} linux && chain .../boot/_linux_menu.ipxe || goto menu
...
iseq ${target} exit && exit || goto menu
```
iPXE evaluates `&&`/`||` strictly left to right (POSIX-shell style, `src/core/exec.c` `system()`), so for `A && B || C` the `C` branch runs whenever `A` fails. With `A` = `iseq ${target} <item>`, that means every item except the first one skipped its own `chain` and ran `goto menu` immediately — redrawing the menu with `--default queue` highlighted, exactly what you saw. `x` failed the same way, which is why Exit behaved like Enter. Only `local` (the first line) was ever reachable.
**Fixed on `main`** (commit `e80a66b`, tagged `v0.8.2` — the version bump is in `Cargo.toml`):
- dispatch is now the canonical iPXE pattern — `goto ${target} || goto menu` followed by one `:label` block per item, so a non-matching item can't fall into a stray `goto menu`;
- menu-to-menu transitions use `chain --replace` (the new menu replaces the old image), so `x` exits to the firmware from any submenu and Back/forward navigation doesn't pile up nested scripts;
- boot entries recover to the menu themselves if a kernel/initrd fetch fails (needed once menus `--replace`);
- plus a few nearby script bugs of the same class: the arch-label probe ended in `|| true` (`true` isn't an iPXE command — non-x86_64/UEFI/arm64 pairs would abort before drawing the menu), Utilities→Back redrew Utilities instead of returning to Tools, `prompt --timeout` aborted NIC Info, and the empty-password check compared against a literal `""` token (iPXE has no quoting).
There's a new `menu_dispatch_tests` suite that runs the generated scripts through a small interpreter mirroring iPXE's `system()`/`process_script()` semantics and asserts each item reaches its expected chain URL — the old lines fail it. `cargo test --workspace` is green.
No firmware rebuild needed — the `snponly.efi`/`ipxe.efi` assets are untouched; only the server-generated scripts changed. So a new `0.8.2` image (or a build from `main`) is enough on the server side.
If you can retest once you're on 0.8.2, that'd be great — particularly Enter on a Linux/Windows submenu item, `x` from the top menu, and `b`/Back from a submenu back to the main menu. If anything still misbehaves, the menu/entry script text you get from Ctrl-B `chain` would pinpoint it.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Environment
OpenPXE v0.8.1
x86_64 UEFI
OpenPXE running in Docker
PXE clients tested:
Both clients show the same behavior
OpenPXE serves
snponly.efiProblem
The OpenPXE iPXE menu is displayed normally and keyboard navigation works:
However, the highlighted item cannot be selected.
xshortcut (item --key x exit) also does not activate Exit.xmoves the selection back to the default Queued Deployment item.The same behavior occurs on both the VM and physical laptop.
Reproduction
The generated main menu contains:
The menu renders correctly, but
choosenever appears to commit the selected item.Important test
I can interrupt the boot with
Ctrl-Band reach:From there:
successfully opens the Linux installer menu.
I can then directly chain:
and Debian 13 successfully boots into the installer.
This confirms that PXE, TFTP, HTTP scripting, OpenPXE ISO handling, and the generated boot scripts are working.
The problem appears to be specifically with interactive menu selection/input.
Request
Could you check the x86_64 UEFI
snponly.efi/ bundled iPXE input configuration and menu-selection behavior in v0.8.1?I can test a patched
snponly.efior development build if useful.Thanks for the detailed report — and especially for the Ctrl-B tests. Hand-chaining
debian-13-7-0-amd64-netinst-sanboot.ipxebooting fine localised this to the menu scripts rather than the network, HTTP/TFTP or the .efi binaries.Root cause was in the scripts OpenPXE generates, not in iPXE selection or your firmware. The dispatch lines looked like this:
iPXE evaluates
&&/||strictly left to right (POSIX-shell style,src/core/exec.csystem()), so forA && B || CtheCbranch runs wheneverAfails. WithA=iseq ${target} <item>, that means every item except the first one skipped its ownchainand rangoto menuimmediately — redrawing the menu with--default queuehighlighted, exactly what you saw.xfailed the same way, which is why Exit behaved like Enter. Onlylocal(the first line) was ever reachable.Fixed on
main(commite80a66b, taggedv0.8.2— the version bump is inCargo.toml):goto ${target} || goto menufollowed by one:labelblock per item, so a non-matching item can't fall into a straygoto menu;chain --replace(the new menu replaces the old image), soxexits to the firmware from any submenu and Back/forward navigation doesn't pile up nested scripts;--replace);|| true(trueisn't an iPXE command — non-x86_64/UEFI/arm64 pairs would abort before drawing the menu), Utilities→Back redrew Utilities instead of returning to Tools,prompt --timeoutaborted NIC Info, and the empty-password check compared against a literal""token (iPXE has no quoting).There's a new
menu_dispatch_testssuite that runs the generated scripts through a small interpreter mirroring iPXE'ssystem()/process_script()semantics and asserts each item reaches its expected chain URL — the old lines fail it.cargo test --workspaceis green.No firmware rebuild needed — the
snponly.efi/ipxe.efiassets are untouched; only the server-generated scripts changed. So a new0.8.2image (or a build frommain) is enough on the server side.If you can retest once you're on 0.8.2, that'd be great — particularly Enter on a Linux/Windows submenu item,
xfrom the top menu, andb/Back from a submenu back to the main menu. If anything still misbehaves, the menu/entry script text you get from Ctrl-Bchainwould pinpoint it.