Troubleshooting & Debugging Guide
This guide provides a layered diagnostic methodology (from physical networking and DHCP/TFTP to HTTP assets, the Subiquity installer, and the K3s Kubernetes cluster), accompanied by real-world error messages and console rescue commands.
1. Layered Diagnostic Tree
2. Layers 1 & 2: Local Network, DHCP & TFTP Handshake
2.1. PXE-E11: ARP timeout or Infinite DHCP... Loop
- Symptom: The console displays
DHCP... /for 30–60 seconds, followed byPXE-E11: ARP timeoutorNo bootable device found. - Root Causes:
- The target client does not receive
DHCPOFFERfrom the router/DHCP server. - The Proxmox VM is attached to the wrong network bridge (e.g.,
vmbr1instead ofvmbr0where DHCP operates). - Physical cable disconnection or incorrect switch port VLAN tag (Access VLAN mismatched with Bun server subnet).
- The target client does not receive
- Remediation:
- Verify Proxmox bridge connectivity:bash
brctl show vmbr0 - Capture DHCP discovery traffic on the router or Bun server:bash
sudo tcpdump -i any -n "port 67 or port 68"
- Verify Proxmox bridge connectivity:
2.2. PXE-E32: TFTP open timeout
- Symptom: The client receives a DHCP IP lease, but halts during TFTP file transfer:
PXE-T01: File not found PXE-E32: TFTP open timeout - Root Causes:
- DHCP Option 66 (
Next-Server) points to an unreachable IP or incorrect host. - Firewall rules (UFW / iptables) on the TFTP server block UDP port 69.
ipxe.efiis missing from the TFTP root directory (/var/lib/tftpboot/).
- DHCP Option 66 (
- Validation Test from another host:bash
# Attempt pulling ipxe.efi over TFTP via CLI: tftp 192.168.250.202 -c get ipxe.efi ls -lh ipxe.efi
3. Layer 3: Bun HTTP Server & Static Assets
3.1. iPXE Reports Connection timed out or HTTP 404 Not Found
- Symptom: iPXE initializes but displays:
http://192.168.250.202:3000/boot.ipxe?mac=... Connection timed out - Root Causes:
- The Bun server daemon is not running (
bun run devordocker compose up -d). BASE_URLin.envis configured ashttp://localhost:3000rather than the accessible LAN IP (http://192.168.250.202:3000).- Host firewall blocks TCP port 3000.
- The Bun server daemon is not running (
- Remediation:
- Review
.env:iniPORT=3000 HOST=0.0.0.0 BASE_URL=http://192.168.250.202:3000 - Open host firewall:bash
sudo ufw allow 3000/tcp
- Review
3.2. iPXE Halts During vmlinuz or initrd Download: Asset not found
- Symptom: Server responds with
Asset not found: ubuntu/24.04/vmlinuz. - Root Cause: Kernel or initrd binaries have not been downloaded into the
assets/directory. - Remediation:
- Run the asset mirroring utility:bash
bun run sync-assets ubuntu --download - Inspect downloaded assets:bash
ls -lh assets/ubuntu/24.04/ # Should contain: vmlinuz (~14MB - 60MB) and initrd (~70MB - 120MB)
- Run the asset mirroring utility:
3.3. Verifying HTTP Range Requests (Status 206)
Verify that Bun properly serves partial byte ranges for large ISO files:
bash
curl -I -r 0-1024 http://192.168.250.202:3000/assets/ubuntu/24.04/vmlinuzThe response headers must contain HTTP/1.1 206 Partial Content and Accept-Ranges: bytes.
4. Layer 4: OS Installer (Subiquity / Cloud-Init)
4.1. OOM Killer: Subiquity Crashes on 4GB–5GB RAM VMs
- Symptom:
- Ubuntu splash screen renders, progress bar advances, and the system abruptly drops to
root@casper-live:~#or outputs:Out of memory: Killed process 1420 (subiquity) total-vm:2840512kB
- Ubuntu splash screen renders, progress bar advances, and the system abruptly drops to
- Root Cause:
- Under
boot_method: http, Casper downloads the complete 2.6GB ISO directly into volatile memory (tmpfs). - Extracting
filesystem.squashfsconsumes an additional 1GB RAM. - The Python-based Subiquity installer requires ~800MB RAM.
- Total memory demand exceeds 4.5GB, prompting the Linux Kernel Out-Of-Memory (OOM) Killer to terminate Subiquity!
- Under
- Definitive Fix:
- Switch the VM configuration to NFS Boot (
boot_method: nfs) inconfig/hosts.yaml:yamlcustom: boot_method: nfs nfs_root: "192.168.250.4:/srv/nfs/ubuntu-24.04" - Under NFS boot, rootfs layers stream on-demand over the network (~300MB RAM consumption), allowing 4GB VMs to provision reliably.
- Switch the VM configuration to NFS Boot (
4.2. Target Storage Device Not Found (target_disk)
- Symptom: Subiquity halts with storage partitioning errors.
- Root Cause:
config/hosts.yamlspecifiestarget_disk: "/dev/sda".- The VM uses a VirtIO Block controller (device named
/dev/vda), or the bare-metal server uses an NVMe SSD (/dev/nvme0n1).
- Remediation:
- Proxmox SCSI / SATA:
/dev/sda. - Proxmox VirtIO Block:
/dev/vda. - NVMe SSD:
/dev/nvme0n1. - Or omit
target_diskto allow Subiquity to select the primary drive usinglayout: direct.
- Proxmox SCSI / SATA:
4.3. Accessing the Emergency Shell & Live Installer Logs
When installation stalls or fails on the console:
- In the Proxmox NoVNC console (or physical keyboard), press:
Ctrl + Alt + F2 (or Alt + F2) - The display switches to an Emergency Shell logged in as root.
- Inspect live logs:bash
# 1. Subiquity detailed server logs tail -n 100 /var/log/installer/subiquity-server-debug.log # 2. Curtin storage and partitioning logs cat /var/log/installer/curtin-install.log # 3. Stream cloud-init logs in real time journalctl -u cloud-init -f - Press
Ctrl + Alt + F1to return to the graphical installer screen.
4.4. Kernel Panic: VFS: Unable to mount root fs on unknown-block(0,0)
- Symptom:
- Immediately following kernel load via PXE / netboot.xyz:
No filesystem could mount root, tried: Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
- Immediately following kernel load via PXE / netboot.xyz:
- Root Causes:
- Version Skew between
vmlinuzand/lib/modules/:vmlinuzdownloaded from an upstream floating netboot mirror does not match the frozen rootfs modules. - Dirty iPXE RAM Buffer from netboot.xyz: Missing
imgfreecommand causes corrupt initrd decompression. - UEFI Command Line Conflict:
initrd=initrdparameter conflicts with the EFI LoadFile2 protocol. - Ramdisk Size Limit: Missing
ramdisk_size=3500000causes buffer overflow during decompression.
- Version Skew between
- Remediation:
- Extract Kernel and Initrd directly from the same official ISO:bash
bsdtar -xf assets/ubuntu/24.04/ubuntu-24.04-live-server-amd64.iso -C /tmp casper/vmlinuz casper/initrd mv /tmp/casper/vmlinuz assets/ubuntu/24.04/vmlinuz mv /tmp/casper/initrd assets/ubuntu/24.04/initrd rm -rf /tmp/casper - Ensure the iPXE script includes
imgfreeandroot=/dev/ram0 ramdisk_size=3500000. - Refer to Kernel/Rootfs Synchronization & netboot.xyz Guide.
- Extract Kernel and Initrd directly from the same official ISO:
4.5. openSUSE Leap Micro 6.2 Issues (Kiwi PXE Netboot & Combustion)
Unlike Ubuntu Subiquity, openSUSE Leap Micro utilizes Kiwi OEM PXE Netboot paired with Combustion firstboot scripts. The following issues are unique to this netboot engine:
4.5.1. Black Screen / Hang After Loading vmlinuz and initrd
- Symptom: iPXE downloads both the kernel and initrd, but immediately hangs on a black screen upon executing
boot. - Root Cause: The file
assets/suse-micro/6.2/initrdwas mistakenly extracted fromopenSUSE-Leap-Micro.x86_64-6.2.initrd(an offline media installer for CD/USB). This offline initrd lacks dracut network and kiwi PXE netboot modules. When the kernel boots withrd.kiwi.install.pxe rd.neednet=1, dracut crashes before activating the console framebuffer. - Remediation:
- Ensure
initrdis sourced frompxeboot.openSUSE-Leap-Micro.x86_64-6.2.initrd(size ~202.8MB / 212,671,947 bytes), which contains the complete PXE networking stack.
- Ensure
4.5.2. failed to fetch http://.../openSUSE...sha256 Followed by Immediate Reboot
- Symptom: The kernel boots into dracut kiwi netboot, but aborts with a failed SHA256 checksum download error and reboots.
- Root Cause: The Kiwi PXE installer strictly verifies the SHA256 digest of the compressed raw image before writing to disk. If the HTTP server returns 404 for
openSUSE-Leap-Micro.x86_64-6.2.sha256, the install sequence terminates immediately. - Remediation:
- Extract and place
openSUSE-Leap-Micro.x86_64-6.2.sha256inassets/suse-micro/6.2/. - A symlink
openSUSE-Leap-Micro.x86_64-6.2.xz.sha256can also be provided for Kiwi variants that look for the full image extension.
- Extract and place
4.5.3. Missing .kernel or .initrd File (HTTP 404 / Broken Symlink)
- Symptom: Kiwi netboot aborts reporting that
openSUSE-Leap-Micro.x86_64-6.2.kernelcannot be fetched. - Root Cause: In the upstream appliance tarball,
openSUSE-Leap-Micro.x86_64-6.2.kernelis a relative symlink pointing topxeboot.openSUSE-Leap-Micro.x86_64-6.2.kernel. Renaming the target tovmlinuzbreaks this symlink. - Remediation:
- Copy rather than rename the source file during extraction.
- Verify that
http://<BUN_IP>/assets/suse-micro/6.2/openSUSE-Leap-Micro.x86_64-6.2.kernelreturnsHTTP 200 OK.
5. Layer 5: Kubernetes K3s Bootstrap
5.1. K3s Service Fails to Start or Node Reports NotReady
- Check Status:bash
ssh homelab@192.168.250.33 "sudo systemctl status k3s" - Common Causes:
- Swap Not Disabled: Kubelet rejects nodes with active swap.
- Verify:
free -h(Swap should show0B). - Disable:
sudo swapoff -a && sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab.
- Verify:
- Missing Kernel Modules: Flannel CNI requires
br_netfilterandoverlay.- Verify:
lsmod | grep br_netfilter. - Load:
sudo modprobe overlay && sudo modprobe br_netfilter.
- Verify:
- Swap Not Disabled: Kubelet rejects nodes with active swap.
5.2. permission denied on kubectl Execution
- Symptom: Running
kubectl get nodesoutputs:error: error loading config file "/etc/rancher/k3s/k3s.yaml": open /etc/rancher/k3s/k3s.yaml: permission denied - Root Cause: The default K3s kubeconfig is owned by
rootwith0600permissions. - Remediation:
- The project's
k3s-single-nodeprofile automatically configureswrite-kubeconfig-mode: "0644"and links~homelab/.kube/config. - Manual repair:bash
sudo chmod 644 /etc/rancher/k3s/k3s.yaml
- The project's
5.3. Remote Kubeconfig Retrieval API
Fetch an automatically rewritten, ready-to-use kubeconfig directly from the Bun server:
bash
# Download kubeconfig with rewritten external server IP
curl -s http://<BUN_IP>:3000/api/kubeconfig/<hostname-or-mac> > kubeconfig-<hostname>
# Pipe directly into kubectl without writing to disk:
curl -s http://<BUN_IP>:3000/api/kubeconfig/<hostname-or-mac> | kubectl --kubeconfig=/dev/stdin get nodes -o wide5.4. Kubeconfig Retrieval Error: Permission denied (publickey,password)
- Symptom: Clicking "Kubeconfig" on the dashboard or querying
/api/kubeconfig/<node>returns502 Bad Gateway:json{ "error": "Failed to fetch kubeconfig from <node> via SSH.", "details": "homelab@<node-ip>: Permission denied (publickey,password,keyboard-interactive).", "hint": "SSH authentication failed. Ensure the server's SSH public key is added to..." } - Root Cause: The iPXE server tries to SSH into the node as the configured user (default
homelab), but the node does not have the server's public key authorized in~/.ssh/authorized_keys, or the server lacks an SSH private key. - Remediation:
- Automated via deploy script: Deploying with
proxmox/deploy-lxc.shautomatically synchronizes your local workstation's SSH key (~/.ssh/id_ed25519or~/.ssh/id_rsa) into the LXC container (/root/.ssh/). - Profile Configuration: Ensure the matching public key is specified under
default.ssh_authorized_keysinconfig/hosts.yamlso newly provisioned nodes trust it during bootstrap. - Manual Node Authorization:bash
ssh <user>@<node-ip> "echo '<SSH_PUBLIC_KEY>' >> ~/.ssh/authorized_keys"
- Automated via deploy script: Deploying with
6. Layer 6: Proxmox Automation (proxmox/create-vm.ts)
6.1. PVE API Error (401 Unauthorized) or 403 Forbidden
- Root Cause: Invalid Proxmox API Token credentials or missing ACL permissions.
- Remediation:
- In Proxmox VE Web UI -> Datacenter -> Permissions -> API Tokens.
- Verify that
root@pam!automationis created with Privilege Separation unchecked (or grantedAdministrator/PVEVMAdminrole). - Update
proxmox/credentials.env.
6.2. CERT_HAS_EXPIRED or SELF_SIGNED_CERT_IN_CHAIN
- Remediation: Set insecure mode in
proxmox/credentials.env:iniPVE_INSECURE=true
7. Diagnostic Matrix & Emergency Rescue Actions
| Symptom | Fault Layer | Immediate Action |
|---|---|---|
Halts at DHCP... with timeout | L1/L2 Network | Check cables, bridge vmbr0, and switch port VLAN tags |
PXE-E32: TFTP open timeout | L3/L4 TFTP | Verify Router Option 66 IP, confirm ipxe.efi presence |
iPXE Connection timed out port 3000 | L7 HTTP | Verify BASE_URL in .env matches LAN IP |
| Subiquity crashes to black console shell | RAM/OOM | Switch to boot_method: nfs in config/hosts.yaml |
| Subiquity disk partitioning error | Storage | Match controller: SCSI (sda), VirtIO (vda), NVMe |
| Leap Micro hangs on black screen after initrd | Kiwi/Initrd | Serve pxeboot.openSUSE-Leap-Micro.x86_64-6.2.initrd instead of offline initrd |
Kiwi halts with failed to fetch ... sha256 | Kiwi Checksum | Supply openSUSE-Leap-Micro.x86_64-6.2.sha256 in assets directory |
Kiwi reports Asset not found: ...kernel | Symlink | Restore valid openSUSE...kernel symlink to pxeboot...kernel |
| Machine continuously reinstalls on reboot | Anti-Loop | Check /api/installed webhook, or run POST /api/reset?mac=... |
kubectl reports permission denied | K3s | Run sudo chmod 644 /etc/rancher/k3s/k3s.yaml |