PXE Boot
FluxDeploy includes a complete PXE boot infrastructure for network-booting machines into the WinPE deployment environment. The implementation uses Microsoft-signed bootmgfw.efi for full Secure Boot compatibility - no need to disable Secure Boot or use unsigned boot loaders.
Architecture
The PXE boot chain:
- DHCP - Client receives boot instructions via ProxyDHCP (option 66 = server IP, option 67 =
bootmgfw.efi) - TFTP - Client downloads
bootmgfw.efi(~1.6 MB), BCD, boot.sdi, and boot.wim (~500 MB) - bootmgfw.efi - Reads BCD, loads boot.sdi as ramdisk SDI, loads boot.wim as ramdisk OS
- WinPE - Boots from ramdisk, starts the FluxDeploy agent
Why bootmgfw.efi
iPXE (including snponly.efi) is not Secure Boot compatible - unsigned EFI binaries are blocked. Since FluxDeploy is UEFI-only, bootmgfw.efi (Microsoft-signed, available on every Windows machine at C:\Windows\Boot\EFI\) is the correct choice.
Enabling PXE
Navigate to Settings > PXE & Network Boot > Core PXE:
- PXE Enabled - Toggle to enable/disable PXE services on the Core server
- TFTP Port - Default 69
- Bind Address - Network interface IP (empty = all interfaces)
Then activate a boot image for PXE on the Boot Images page.
TFTP Performance
The Transfer Speed setting selects one of three TFTP tuning modes:
| Mode | Block Size | Window Size | When to use |
|---|---|---|---|
| High | 65,464 bytes | 64 | Flat gigabit LANs with physical NICs only. Blocks exceed a 1500-byte MTU and IP-fragment - do not use across VPN, SD-WAN, or unknown networks. |
| Medium (default) | 1,456 bytes | 4 | Matches Microsoft WDS's out-of-box tuning. Blocks fit inside a standard 1500-byte MTU so packets never fragment - safe anywhere. |
| Low | 1,456 bytes | 1 | RFC-minimum window - one block in flight at a time. The most conservative option; use if Medium still times out (e.g. some VMware environments). |
Where to set it:
- Core server - Settings > PXE & Network Boot > Core PXE (card "Boot Speed"). After changing it, re-activate the PXE boot image on the Boot Images page for the change to take effect.
- All relays - Settings > PXE & Network Boot > Relay Defaults sets a global default for every relay (leave unset to let relays use their own default). Propagated via heartbeat, typically within ~15 seconds - no relay restart needed.
- Per site - Each relay can override the global default individually; see Sites Management. The effective mode is the per-site override if set, otherwise the global relay default. Each site also reports the mode it is actually running.
Note: PXE clients must be fully rebooted (hard stop/reset, not a soft reboot) to pick up new TFTP settings mid-session.
If the same client IP fails three complete transfers within 10 minutes, the TFTP server logs a warning in the PXE/TFTP log suggesting a more conservative mode for that site. It never downgrades automatically - the mode is always admin intent.
ProxyDHCP
FluxDeploy includes a built-in ProxyDHCP server that eliminates the need to modify your existing DHCP infrastructure:
- Windows - Embedded
ProxyDhcpServicelistens on UDP ports 67 and 4011 - Linux - Auto-configured dnsmasq (when
ManageDnsmasq=true)
Port 67 binding is best-effort - it fails gracefully if another DHCP server runs on the same machine.
TFTP Directory Structure
{BootFilesPath}/tftp/
├── bootmgfw.efi # Microsoft-signed UEFI boot manager (flat path)
├── Boot/
│ ├── BCD # PXE-specific Boot Configuration Data
│ ├── boot.sdi # System Deployment Image
│ ├── x64/
│ │ └── bootmgfw.efi # Same binary, directory-qualified path
│ └── Fonts/*.ttf # Boot screen fonts
└── sources/
└── boot.wim # WinPE boot image
bootmgfw.efi is staged at both paths on purpose, and which one a client fetches depends on who
answers DHCP:
- Our own ProxyDHCP (the default
ProxyDhcpPXE mode) namesBootdootmgfw.efi, matching what real WDS hands out. - A customer DHCP server carrying Option 67 (
DhcpServerOptions/DhcpHelpermodes) conventionally names the flatbootmgfw.efi.
There is no path remapping between them, so a client asking for the copy that is missing gets a hard TFTP "file not found", which the machine reports on its console as "A boot image was not found." Everything in this list except the fonts must be present before a site can complete a boot; fonts only affect how the boot screen looks. Core will not mark a relay's boot image Synced until the relay reports holding all of them - see Relay sites.
HTTP Fallback
Boot delivery is exclusively TFTP (bootmgfw.efi). The iPXE/wimboot HTTP fallback that used to run on port 5101 was removed in 1.3.6.114 - every modern UEFI client boots the Microsoft-signed bootmgfw.efi over TFTP under Secure Boot, which the fallback could not do.
Port 5101 is still bound, but for exactly one request that cannot use HTTPS: the WinPE agent's boot breadcrumb (POST /api/pxe/agent-boot), which is sent before TLS pinning has succeeded. Anything else sent to that port is answered 404 with a sentence pointing at the HTTPS port; the ACME http-01 challenge has its own listener and never uses it.
Relay PXE fix actions
The PXE fix actions (restart PXE bindings, regenerate boot files, resync boot.wim, TFTP self-test, reset log cursors) are run from the site's PXE & Health tab on Core, which queues them to the relay through its heartbeat. The relay's own /api/pxe/tech/* endpoints for those actions require the relay's callback credential in X-Api-Key and answer 401 without it, so a workstation on the LAN can no longer delete a site's boot.wim or abort its TFTP transfers. The firewall-state capture stays readable from the LAN like the /pxe-status page itself.
ProxyDHCP bind address
When Pxe:BindAddress is set, the ProxyDHCP listener on port 4011 binds to that address only. Port 67 stays on every address on purpose: a PXE DISCOVER is a broadcast, and a socket bound to one unicast address does not receive broadcasts on Windows.
Relay PXE
Each relay site can run its own PXE services independently. PXE settings are propagated from Core to relays via heartbeat:
- Global relay defaults - Settings > PXE & Network Boot > Relay Defaults holds three settings in one panel with one Save: PXE boot, PXE logging and TFTP transfer speed. Each is a tri-state: Enabled on all relays, Disabled on all relays, or Not set (each relay uses its own setting). Changes propagate on the next heartbeat (~2 minutes).
- Per-site override - Configured per relay on the site's General tab. A per-site setting always beats the global default; the panel warns when any site has one and offers to clear them all.
- Not set - When the global default is cleared, each relay uses its own local PXE configuration (default: enabled).
- Core PXE is separate - None of this affects PXE on the Core server, which is managed on the Core PXE tab.
- Static PXE files (bootmgfw.efi, BCD, boot.sdi, fonts) are put in place automatically as part of the boot image sync - a Linux relay pulls them from Core, a Windows relay produces them locally - so a relay is ready to serve a boot as soon as it reports the image as synced. A relay that cannot produce its BCD says so in its log and is held out of Synced rather than shown as ready.
DHCP for relay sites
Each relay includes a ProxyDHCP server that handles PXE on its local subnet automatically. For PXE boot from other VLANs, point the DHCP server that serves that VLAN at the relay's IP address - not at Core - so clients download boot files locally and the WAN link stays clear.
| DHCP Option | Value | Description |
|---|---|---|
| 066 (Boot Server Host Name) | <relay IP address> |
IP address of the relay server for that site |
| 067 (Bootfile Name) | bootmgfw.efi |
Microsoft-signed UEFI boot loader |
Firewall requirements, from the client VLAN to the relay:
UDP 69- TFTP (boot files)UDP 1024-65535- TFTP data (ephemeral ports)TCP 8400- HTTPS (agent to relay, after WinPE boots)
Microsoft DHCP Server, per scope (one VLAN to one relay)
- Open DHCP Manager (
dhcpmgmt.msc) - Expand your server > IPv4 > select the scope for the target VLAN
- Right-click Scope Options > Configure Options...
- Check 066 Boot Server Host Name > enter the relay's IP address
- Check 067 Bootfile Name > enter
bootmgfw.efi - Click OK
# Replace ScopeId and the relay IP with your values
Set-DhcpServerv4OptionValue -ScopeId "192.168.10.0" -OptionId 66 -Value "10.0.1.50"
Set-DhcpServerv4OptionValue -ScopeId "192.168.10.0" -OptionId 67 -Value "bootmgfw.efi"
ISC DHCP / Kea (Linux)
subnet 192.168.10.0 netmask 255.255.255.0 {
range 192.168.10.100 192.168.10.200;
next-server 10.0.1.50; # Relay IP
filename "bootmgfw.efi";
}
Relay IP addresses are shown on the Sites page.
Same subnet vs. other VLANs
- Same subnet - PXE works automatically. The built-in ProxyDHCP server answers alongside your existing DHCP server, so no network changes are needed.
- Different subnet / VLAN - Broadcast ProxyDHCP traffic does not cross a router, so the DHCP server that serves that VLAN has to carry the boot options itself. See DHCP server configuration.
- Relay sites - Each relay runs its own PXE server. Control relay PXE on Settings > PXE & Network Boot > Relay Defaults, or per-site on the Sites page. For a VLAN served by a relay, point option 066 at that relay's IP, not at Core.
PXE Mode
The PXE Mode setting on Settings > PXE & Network Boot > Core PXE decides whether FluxDeploy competes on UDP/67:
- ProxyDHCP (default) - Core answers on UDP/67 alongside the customer DHCP server and fills in the boot file information itself. Use this when the network's DHCP server has no PXE configuration.
- DHCP Server Options - Core stays on UDP/4011 and UDP/69 for clients that ask, but stops answering on UDP/67. Use this when the customer's DHCP server (OPNsense, Windows DHCP, Cisco, ...) is already configured to deliver options 66 and 67. It also fixes the dual-OFFER server-identifier rejection seen on strict UEFI clients (Hyper-V Gen 2, Dell Latitude, Lenovo ThinkPad).
DHCP server configuration
For PXE boot from other VLANs/subnets, configure the DHCP server that serves that VLAN with:
| DHCP Option | Value | Description |
|---|---|---|
| 066 (Boot Server Host Name) | FluxDeploy server IP (or the relay serving that site) | Where the client fetches boot files from |
| 067 (Bootfile Name) | bootmgfw.efi |
Microsoft-signed UEFI boot loader (Secure Boot compatible) |
Firewall requirements, from the client VLAN to the FluxDeploy server:
UDP 69- TFTP (boot files)UDP 1024-65535- TFTP data (ephemeral ports)TCP 8400(or whichever HTTPS port the server is published on) - agent to server, after WinPE boots
Microsoft DHCP Server (Windows Server)
Option A: scope-level (recommended - applies to one VLAN)
- Open DHCP Manager (
dhcpmgmt.msc) - Expand your server > IPv4 > select the scope for the target VLAN
- Right-click Scope Options > Configure Options...
- Check 066 Boot Server Host Name > enter the FluxDeploy server IP
- Check 067 Bootfile Name > enter
bootmgfw.efi - Click OK
Option B: server-level (applies to all scopes)
- Right-click Server Options > Configure Options...
- Set options 066 and 067 as above
Option C: PowerShell
# Scope-level (replace ScopeId with your subnet, and the IP with your server's)
Set-DhcpServerv4OptionValue -ScopeId "192.168.10.0" -OptionId 66 -Value "192.168.10.5"
Set-DhcpServerv4OptionValue -ScopeId "192.168.10.0" -OptionId 67 -Value "bootmgfw.efi"
# Or server-level (all scopes)
Set-DhcpServerv4OptionValue -OptionId 66 -Value "192.168.10.5"
Set-DhcpServerv4OptionValue -OptionId 67 -Value "bootmgfw.efi"
ISC DHCP / Kea (Linux)
ISC dhcpd.conf
subnet 192.168.10.0 netmask 255.255.255.0 {
range 192.168.10.100 192.168.10.200;
option routers 192.168.10.1;
next-server 192.168.10.5;
filename "bootmgfw.efi";
}
Kea dhcp4.conf
{
"subnet4": [{
"subnet": "192.168.10.0/24",
"next-server": "192.168.10.5",
"boot-file-name": "bootmgfw.efi"
}]
}
Cisco Meraki
Meraki sets this per VLAN on whichever device is the DHCP server for it: an MX appliance (Security & SD-WAN > Configure > DHCP) or an MS layer-3 switch (Switching > Configure > Routing & DHCP, then edit the interface). Find the section for the VLAN your devices boot on and set:
| Meraki field | Value |
|---|---|
| Boot options | Boot options enabled |
| Boot next-server | The FluxDeploy server IP, or the relay that serves this site |
| Boot filename | bootmgfw.efi |
Click Save. Then in FluxDeploy set PXE Mode to DHCP Server Options, so FluxDeploy stops answering alongside the Meraki: for Core in Settings > PXE & Network Boot > Core PXE, for a relay in Sites > (the site) > General. Two answers to the same broadcast makes some strict UEFI firmware reject the boot (see PXE Mode).
Notes:
- Use the IP address, not a hostname. Many UEFI clients only accept an IP address in this field.
- If a client gets an address but never starts the TFTP download, its firmware may read only the
numbered DHCP options and ignore Meraki's boot fields. Add them under Custom DHCP options on the
same VLAN: code
66, typeText, the server IP; and code67, typeText,bootmgfw.efi. - The VLAN still needs to reach the FluxDeploy server on the ports listed above. On an MX, check the Layer 3 firewall rules if the booting VLAN is segmented from the server's.
Router / firewall (generic)
Most enterprise routers and firewalls (Cisco, pfSense, Sophos, FortiGate) support DHCP options 66/67 in their DHCP server settings:
- Next Server / TFTP Server / Boot Server - the FluxDeploy server IP
- Boot File / Filename -
bootmgfw.efi
Refer to your vendor's documentation for the exact setting location. Some vendors use "PXE" or "Network Boot" terminology.
PXE Logging
Detailed TFTP and ProxyDHCP logging can be enabled in Settings > PXE & Network Boot. Logs are written to logs/pxe/pxe-{date}.log with daily rolling.
Troubleshooting a boot: Activity > PXE Activity
Everything about network boot is on one page, Activity > PXE Activity (/activity/pxe). There is
no second place to look - the PXE and TFTP log used to be a category of Server Logs and is a tab here
now, so the wire events and the written log sit side by side.
At the top of the page is the server selector. On Core it lists this server and every relay site, and
the choice is in the address (?server=site-3), so a view can be linked to a colleague and lands on
the same relay.
Wire Events
The live ring buffer of what the listeners actually saw: every DhcpDiscoverIn, DhcpRequestIn,
DhcpDropped, DhcpOfferOut, DhcpAckOut, TftpRrq, TftpOackSent, TftpOackTimeout,
TftpComplete, TftpError and TftpAbort. Filter by client IP, MAC, event kind or how recent, and
click a row to decode the DHCP options that arrived with it (arch, vendor class, client UUID).
Auto-refreshes every 3 seconds. Pause freezes the view while you read, Clear empties the buffer, and Download JSON exports what is on screen for a ticket.
The buffer is in memory, so it starts empty after a restart. For anything older, use the log tab.
TFTP fetch test
The collapsed TFTP fetch test panel does a loopback read of one file from the TFTP root. Use it to localize a broken boot chain by walking it in order:
bootmgfw.efi (and Boot/x64/bootmgfw.efi) -> Boot/BCD -> Boot/boot.sdi -> sources/boot.wim
The first one that fails is the file to fix. Each test also appears as a TftpRrq plus
TftpComplete/TftpError pair in the table below it.
PXE / TFTP Log
Direct link: /activity/pxe/log. The same server's written log, which survives a restart:
- TFTP file transfer requests and completions
- ProxyDHCP request/response pairs
- HTTP boot file serving
- Client IP addresses and requested files
For this server, that is the logs/pxe/pxe-{date}.log files, one per day, with a file picker and a
line filter. For a selected relay site, it is the pxe and tftp lines the relay streams up on its
heartbeat, by day. Refresh re-reads either one.
Note: PXE logging is off by default for performance, so this tab can legitimately be empty on a working server. Turn it on in Settings > PXE & Network Boot (Core PXE tab or Relay Defaults tab); it takes effect immediately, no restart. Wire Events does not depend on it.
The old addresses /activity/logs/pxe and /logs/pxe redirect here.