I was working on an old Dell PowerEdge R610 server and hit a wall I did not expect: it flatly refused to USB boot. No combination of FAT32, ExFAT, GUID partition maps, or dd-written images would get the 11th-generation Dell to recognize a flash drive as a boot source. The R610 predates reliable UEFI USB boot support. My first thought was iDRAC6 virtual media, but that turned out to be completely broken on modern Macs (I wrote up the full story of why in Why iDRAC6 Virtual Media Is Broken on Modern Macs). The server has a DVD drive, but I did not have any blank DVDs lying around. With a 2.7GB Ubuntu Server ISO sitting on my MacBook, the obvious path was PXE: network boot the server straight from the MacBook.
The setup worked beautifully once I got the pieces aligned: my MacBook ran the TFTP and HTTP servers, my Ubiquiti Dream Machine handled DHCP and pointed the R610 at the MacBook for boot files, and the whole thing installed Ubuntu without a single USB stick. Here is the complete walkthrough so you can reproduce it.
How PXE Boot Works (The 30-Second Version)
PXE (Preboot Execution Environment) is a standard that lets a computer boot from the network instead of from local storage. The sequence is:
- The target machine powers on and its network card requests an IP address via DHCP.
- The DHCP server (your router) replies with an IP address plus a pointer to a TFTP server and a boot filename (DHCP options 66 and 67).
- The machine downloads the tiny bootloader files from the TFTP server.
- The bootloader loads the Linux kernel and initrd into RAM.
- The kernel initializes a real network stack and downloads the full ISO over HTTP.
- The Ubuntu installer launches.
The key insight: TFTP is only for the small boot files; HTTP carries the heavy ISO. You split the work across two servers (both running on your MacBook) because TFTP is far too slow for a 2.7GB transfer.
What You Need
- A MacBook (Intel or Apple Silicon) connected to your network, ideally over Ethernet.
- A target server or machine that supports PXE boot (the Dell R610 does, as do most servers from the last 15 years).
- A router or DHCP server you control (this guide uses a Ubiquiti Dream Machine; any router with DHCP options 66/67 works).
- An Ubuntu Server ISO downloaded to your MacBook.
- Both machines on the same wired LAN (PXE does not work over Wi-Fi).
Step 1: Find Your MacBook's Local IP Address
Every configuration file references your MacBook's IP. Find it first:
ifconfig | grep "inet "
Look for the address on your active interface (e.g. 192.168.1.59 on en0). Write this down; you will use it everywhere. For the rest of this guide I will use 192.168.1.59 as the example. Type your own address into the Customize the commands box at the top of this article and every code sample below will update automatically — or just substitute it manually as you go.
If your MacBook is on Wi-Fi, strongly consider plugging in a USB-C Ethernet adapter for the duration. Serving 2.7GB over Wi-Fi to a wired server adds a wireless hop that throttles the transfer dramatically.
Step 2: Download the Ubuntu Server ISO
Download the Ubuntu Server ISO for the release you want to install. Save it to your Downloads folder. For this guide the file is:
~/Downloads/ubuntu-26.04-live-server-amd64.iso
Important: Whatever version you download here is the version whose kernel files you must extract later. The netboot kernel and the ISO must match exactly or the installer will panic with "Unable to find a live file system on the network."
Step 3: Start the macOS TFTP Server
macOS ships with a TFTP server that serves files from /private/tftpboot. Start it:
sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist
sudo launchctl start com.apple.tftpd
Ensure the directory has the right permissions:
sudo chmod 755 /private/tftpboot
Test the TFTP server locally
Verify it works before pointing a server at it:
cd ~
tftp 127.0.0.1
At the tftp> prompt, try fetching a file you know is there. If you have not placed any files yet, you can skip this and come back after Step 5. Once files exist:
tftp> get ubuntu/pxelinux.0
tftp> quit
ls -l pxelinux.0
If you see the file (around 42KB), TFTP is working. If it times out, reset the daemon:
sudo launchctl unload -F /System/Library/LaunchDaemons/tftp.plist
sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist
sudo launchctl start com.apple.tftpd
Step 4: Start the macOS Apache HTTP Server
The large ISO is served over HTTP by macOS's bundled Apache. Start it:
sudo apachectl start
Copy the ISO into Apache's document root:
sudo cp ~/Downloads/ubuntu-26.04-live-server-amd64.iso /Library/WebServer/Documents/
Verify it is reachable by opening this URL in Safari on your MacBook:
http://192.168.1.59/ubuntu-26.04-live-server-amd64.iso
If the browser starts downloading the file, Apache is serving it correctly. If you get "Site can't be reached," confirm the file is actually in /Library/WebServer/Documents/ with ls /Library/WebServer/Documents/ and confirm Apache is running with sudo apachectl status.
Step 5: Extract the Matching Kernel Files from the ISO
This is the step that tripped me up the first time. You need two files from inside the ISO: the Linux kernel (vmlinuz) and the initial ramdisk (initrd). They must come from the same Ubuntu release as your ISO.
macOS Finder often throws "no mountable file systems" when you double-click a hybrid Linux ISO. Use the terminal instead.
Method A: Force-mount the ISO with hdiutil
hdiutil attach -nomount ~/Downloads/ubuntu-26.04-live-server-amd64.iso
This prints a list of partitions (e.g. /dev/disk3s1, /dev/disk3s2). Note the one labeled Linux or CD9660. Mount it:
mkdir ~/Desktop/ubuntu_mnt
sudo mount -t cd9660 /dev/disk3s1 ~/Desktop/ubuntu_mnt
(Replace disk3s1 with your actual partition identifier.) The casper folder inside contains vmlinuz and initrd.
Method B: Extract with tar (no mounting required)
mkdir -p ~/Desktop/ubuntu-extract && cd ~/Desktop/ubuntu-extract
tar -xf ~/Downloads/ubuntu-26.04-live-server-amd64.iso casper/vmlinuz casper/initrd
Copy the kernel files into the TFTP directory
Regardless of which method you used, copy the files into place. The PXELINUX config expects the kernel to be named linux, so rename vmlinuz on the way in:
sudo mkdir -p /private/tftpboot/ubuntu
sudo cp ~/Desktop/ubuntu-extract/casper/vmlinuz /private/tftpboot/ubuntu/linux
sudo cp ~/Desktop/ubuntu-extract/casper/initrd /private/tftpboot/ubuntu/initrd
If you used Method A, substitute ~/Desktop/ubuntu_mnt/casper/ as the source path.
Clean up when done:
hdiutil detach /dev/disk3
rm -rf ~/Desktop/ubuntu-extract ~/Desktop/ubuntu_mnt
Download the PXELINUX bootloader files
The netboot tarball from Canonical contains pxelinux.0, ldlinux.c32, and the pxelinux.cfg directory structure. Download and extract them:
cd ~/Downloads
wget https://releases.ubuntu.com/26.04/ubuntu-26.04-netboot-amd64.tar.gz
tar -xvf ubuntu-26.04-netboot-amd64.tar.gz
Copy the bootloader files into the TFTP directory:
sudo cp ~/Downloads/amd64/pxelinux.0 /private/tftpboot/ubuntu/
sudo cp ~/Downloads/amd64/ldlinux.c32 /private/tftpboot/ubuntu/
sudo mkdir -p /private/tftpboot/ubuntu/pxelinux.cfg
If the version-specific URL 404s (Canonical rotates point releases), browse to releases.ubuntu.com/<version>/ and grab the current netboot-amd64.tar.gz filename.
Step 6: Create the PXELINUX Configuration File
The bootloader reads its menu from pxelinux.cfg/default. Create it:
sudo nano /private/tftpboot/ubuntu/pxelinux.cfg/default
Paste this exact configuration (replace 192.168.1.59 with your MacBook's IP):
DEFAULT install
LABEL install
KERNEL linux
INITRD initrd
APPEND root=/dev/ram0 ramdisk_size=3000000 ip=dhcp url=http://192.168.1.59/ubuntu-26.04-live-server-amd64.iso ds=nocloud cloud-config-url=/dev/null ---
Save and exit (Ctrl+O, Enter, Ctrl+X in nano).
What each APPEND parameter does
root=/dev/ram0: Mount the root filesystem from the ramdisk.ramdisk_size=3000000: Reserve roughly 3GB of RAM to hold and unpack the ISO without running out of space.ip=dhcp: Configure the network interface via DHCP as soon as the kernel loads.url=http://192.168.1.59/ubuntu-26.04-live-server-amd64.iso: The path to the ISO on your MacBook's Apache server.ds=nocloud cloud-config-url=/dev/null: Tell cloud-init to stop hunting for an external metadata source, which prevents the mount freeze that causes "Unable to find a live file system on the network."---: Separator between kernel parameters and userspace parameters.
Step 7: Configure DHCP on the Ubiquiti Dream Machine
With the MacBook handling TFTP and HTTP, let your Dream Machine handle DHCP and point clients at the MacBook for boot. You do not need dnsmasq on the MacBook — shut it down if you previously started it:
sudo brew services stop dnsmasq
In the UniFi Network dashboard:
- Open Settings (gear icon) > Networks.
- Click the network/VLAN your target server is connected to (usually Default).
- Scroll down to the Advanced section and expand it.
- Find the DHCP section and toggle Network Boot on.
- Fill in the two fields:
- TFTP Server (Option 66):
192.168.1.59(your MacBook's IP) - Boot File Name (Option 67):
ubuntu/pxelinux.0
- TFTP Server (Option 66):
- Click Apply Changes at the bottom.
That is the entire router-side configuration. The UDM now tells every PXE client on that network: "Get your IP from me, then go to 192.168.1.59 and download ubuntu/pxelinux.0."
Step 8: Boot the Target Server
On the Dell R610 (or your target machine):
- Connect the server to the network with an Ethernet cable (PXE does not work over Wi-Fi).
- Power it on and enter the boot menu by tapping F12 (Dell) during POST. Other common keys: F11 (MSI/ASRock), F8 (ASUS), F2 to enter BIOS and change boot order.
- Select Network Boot, PXE Boot, or Onboard NIC.
- The server requests an IP from the Dream Machine, which replies with the IP plus the pointer to your MacBook.
- The server downloads
pxelinux.0from your MacBook's TFTP server and executes it.
You should see the PXELINUX screen appear, followed by Loading linux... and Loading initrd.... The TFTP stage takes a few seconds to a minute depending on network latency. Once the kernel boots, the screen clears and the system reaches out to your Apache server to stream the 2.7GB ISO over HTTP. On a wired Gigabit connection this takes 30 to 40 seconds. When the download completes, the Ubuntu Subiquity installer launches and you are in the standard setup flow.
Selecting the boot drive
When you reach the Ubuntu Storage Configuration screen, you will see your available disks listed under AVAILABLE DEVICES. On my R610 there was a 476GB drive and a 3.6TB drive. To boot off the 476GB volume:
- Highlight the 476GB disk and press Enter.
- Select Use as Boot Device. The installer creates the necessary boot partitions automatically for your Legacy BIOS setup.
- Confirm the main partition is mounted at
/(root) in the FILE SYSTEM SUMMARY at the top. If not, highlight the partition, press Enter, select Edit, and set the mount point to/. - Arrow down to Done and press Enter to proceed to user profile setup.
From here it is a standard Ubuntu install. Complete the user, timezone, and SSH options, let it install to disk, and reboot.
Troubleshooting
"No boot device available" (UEFI mismatch)
If your target machine is booting in UEFI mode, pxelinux.0 will not work because PXELINUX is a Legacy BIOS bootloader. You need the UEFI bootloader instead. Copy the UEFI files into your TFTP directory:
sudo cp ~/Downloads/amd64/grubx64.efi /private/tftpboot/ubuntu/
sudo cp ~/Downloads/amd64/bootx64.efi /private/tftpboot/ubuntu/
Then change the Dream Machine's Boot File Name (Option 67) from ubuntu/pxelinux.0 to ubuntu/bootx64.efi and click Apply Changes.
UEFI booting uses GRUB instead of PXELINUX, so it looks for a config file at grub/grub.cfg. Create it:
sudo mkdir -p /private/tftpboot/ubuntu/grub
sudo nano /private/tftpboot/ubuntu/grub/grub.cfg
Paste this configuration (replace 192.168.1.59 with your MacBook's IP):
set default="0"
set timeout=5
menuentry "Ubuntu Installer (UEFI)" {
set gfxpayload=keep
linux /ubuntu/linux ip=dhcp url=http://192.168.1.59/ubuntu-26.04-live-server-amd64.iso autoinstall ---
initrd /ubuntu/initrd
}
On the Dell R610, if UEFI gives you trouble, you can also switch the boot mode back to Legacy BIOS in the BIOS setup (F2 during POST) and use the original PXELINUX configuration. The R610 supports both modes.
"Unable to find a live file system on the network"
This means the kernel booted but could not mount the ISO. Two causes:
-
Version mismatch (most common): Your
linuxandinitrdfiles in/private/tftpboot/ubuntu/do not match the ISO release. If you pulled the kernel from a 24.04 netboot tarball but are serving a 26.04 ISO, the kernel cannot read the filesystem. Re-extractvmlinuzandinitrdfrom thecasperfolder of your target ISO as described in Step 5. -
Missing kernel parameters: Ensure your
pxelinux.cfg/defaultAPPEND line includesroot=/dev/ram0,ramdisk_size=3000000, andds=nocloud cloud-config-url=/dev/null. Without the ramdisk size, the kernel runs out of room to unpack the ISO. Without the cloud-init suppression, the boot hangs waiting for a metadata source.
The HTTP ISO download is slow
If the progress bar counting up to 2783M crawls, check three things:
- Wi-Fi on the MacBook: If your MacBook is on Wi-Fi, plug it into Ethernet. The 2.7GB transfer needs the full Gigabit path.
- iDRAC virtual console overhead: If you are watching the boot through the iDRAC6 virtual console, the management interface can throttle or inspect the background network stream. This is cosmetic; the install still proceeds.
- Apache buffer size: macOS's default Apache config is tuned for low power, not large file transfers. For a one-time install this is usually fine, but if you need more throughput, consider serving the ISO with
python3 -m http.server 80 --directory /Library/WebServer/Documentsinstead.
TFTP test times out
If your local tftp 127.0.0.1 test fails with "Transfer timed out," the macOS TFTP daemon is asleep or misconfigured. Reset it:
sudo launchctl unload -F /System/Library/LaunchDaemons/tftp.plist
sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist
sudo launchctl start com.apple.tftpd
Also confirm /private/tftpboot and its contents are world-readable (chmod -R 755 /private/tftpboot).
File Layout Summary
| Location | Contents |
|---|---|
/private/tftpboot/ubuntu/ | linux, initrd, pxelinux.0, ldlinux.c32 |
/private/tftpboot/ubuntu/pxelinux.cfg/ | default (the PXELINUX menu config) |
/private/tftpboot/ubuntu/grub/ | grub.cfg (only needed for UEFI boots) |
/Library/WebServer/Documents/ | ubuntu-26.04-live-server-amd64.iso (the heavy ISO) |
Think of it as two stations: TFTP is the ignition station that hands over the tiny boot files, and Apache is the cargo station that streams the full ISO once the kernel is running.
Why PXE Beats USB for Old Servers
The Dell R610 is from an era where USB boot support was unreliable at best. iDRAC6 virtual media would have been the obvious fallback, but it is completely broken on modern Macs (see Why iDRAC6 Virtual Media Is Broken on Modern Macs for the full diagnosis). And while the server has a DVD drive, who keeps blank DVDs around in 2026? PXE sidesteps all of it: no physical media, no USB port compatibility issues, no Java native library crashes. You point the DHCP server at your MacBook, start two built-in macOS services, and the server installs over the network.
The same approach works for any server with a PXE-capable network card. If you have a rack of older Dell, HP, or Supermicro servers that need reprovisioning, PXE from a MacBook is a fast way to do it without burning a stack of USB sticks or wrestling with finicky legacy boot menus.