> For the complete documentation index, see [llms.txt](https://docs.layeronecloud.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.layeronecloud.com/pve-microvm/troubleshooting.md).

# Troubleshooting

Source project: `pve-microvm` (migrated from `docs/troubleshooting.md`). Run commands from the code checkout and directory specified below, not from this documentation repository.

## "option 'X' is not supported with microvm machine type" <a href="#option-x-is-not-supported-with-microvm-machine-type" id="option-x-is-not-supported-with-microvm-machine-type"></a>

Remove the unsupported option:

```bash
qm set <vmid> --delete <option>
```

Common: `bios`, `efidisk0`, `usb0`, `hostpci0`.

## "microvm requires a kernel" <a href="#microvm-requires-a-kernel" id="microvm-requires-a-kernel"></a>

Specify a kernel via `--args`:

```bash
qm set <vmid> --args '-kernel /usr/share/pve-microvm/vmlinuz -append "console=ttyS0 root=/dev/vda rw"'
```

## No console output <a href="#no-console-output" id="no-console-output"></a>

1. Ensure `console=ttyS0` is in the kernel command line
2. Ensure `serial0: socket` and `vga: serial0` are in the VM config
3. Use `qm terminal <vmid>` (not noVNC)
4. Press Enter — the shell may be waiting for input

## Kernel panic: "No working init found" <a href="#kernel-panic-no-working-init-found" id="kernel-panic-no-working-init-found"></a>

1. Verify the rootfs has `/sbin/init` (or use `init=/sbin/microvm-init` in append)
2. Verify root device: `root=/dev/vda` matches the actual root disk
3. Verify ext4 is compiled into the kernel (not as a module)
4. Debug: add `rdinit=/bin/sh` to kernel append to get a pre-init shell

## Network not working <a href="#network-not-working" id="network-not-working"></a>

1. Check bridge exists: `brctl show`
2. Check tap device: `ip link show tap<vmid>i0`
3. Inside guest: `ip link` — may need DHCP or static config
4. Try: `udhcpc -i eth0` (Alpine) or `dhclient eth0` (Debian)

## "KVM virtualisation configured, but not available" <a href="#kvm-virtualisation-configured-but-not-available" id="kvm-virtualisation-configured-but-not-available"></a>

```bash
ls -la /dev/kvm
modprobe kvm_intel   # or kvm_amd
```

For nested VMs, enable nested virtualization on the outer hypervisor.

## `qm shutdown` or `qm reboot` times out <a href="#qm-shutdown-or-qm-reboot-times-out" id="qm-shutdown-or-qm-reboot-times-out"></a>

MicroVMs do not have a conventional ACPI power button. Graceful power operations therefore require the QEMU guest agent and a working guest shutdown command.

Releases before v0.3.17 also omitted PVE's qmeventd monitor socket. The guest could power off correctly while QEMU remained in `paused (shutdown)` because it runs with `-no-shutdown`.

Upgrade `pve-microvm`, restart the VM so the new QEMU command line is used, and verify the qmeventd monitor is present. Since v0.3.20, package installation also reloads `pvedaemon`; this is required because its long-lived Perl process would otherwise keep the previous `MicroVM.pm` for UI, API, `pvesh`, and automation requests. Fresh `qm` processes do not have that cache.

```bash
qm showcmd <vmid> --pretty | grep -E 'qmp-event|qmeventd.sock'
```

Existing Debian/Ubuntu guests built without D-Bus also need:

```bash
qm guest exec <vmid> -- bash -lc \
  'apt-get update && apt-get install -y dbus && systemctl enable --now dbus'
```

Then verify both lifecycle operations. A reboot must change the guest boot ID; a shutdown must leave no QEMU process behind:

```bash
qm reboot <vmid>
qm shutdown <vmid> --timeout 60
qm status <vmid>
```

Guests created with `--no-agent` still have no guaranteed graceful shutdown path; use `qm stop` or install/enable the QEMU guest agent.

## Patches not applied after qemu-server upgrade <a href="#patches-not-applied-after-qemu-server-upgrade" id="patches-not-applied-after-qemu-server-upgrade"></a>

Do not restore an old backup before applying patches, because it may belong to an older qemu-server version. Apply the current patch set directly:

```bash
rm -f /usr/share/pve-microvm/.applied
/usr/share/pve-microvm/pve-microvm-patch apply
systemctl restart pvedaemon
```

## pve-oci-import fails: "required tool not found" <a href="#pve-oci-import-fails-required-tool-not-found" id="pve-oci-import-fails-required-tool-not-found"></a>

```bash
apt update && apt install skopeo umoci qemu-utils
```

## pve-oci-import fails: "failed to import disk" <a href="#pve-oci-import-fails-failed-to-import-disk" id="pve-oci-import-fails-failed-to-import-disk"></a>

The VM must exist first:

```bash
qm create <vmid> --machine microvm --memory 256
pve-oci-import --image alpine:3.21 --vmid <vmid>
```

## Linked qcow2 clone drops into the initrd or BusyBox <a href="#linked-qcow2-clone-drops-into-the-initrd-or-busybox" id="linked-qcow2-clone-drops-into-the-initrd-or-busybox"></a>

Check the format passed to QEMU:

```bash
qm showcmd <vmid> --pretty | grep 'drive-scsi0'
```

A file-backed qcow2 clone must include `format=qcow2`; LVM-thin and ZFS block volumes normally use `format=raw`. Releases before v0.3.23 could call a nonexistent PVE format API, swallow the error, and pass a qcow2 overlay as raw. Do not rename the image or change `root=/dev/vda` as a workaround.

With cloud-init, the supported order is:

```
scsi0 -> /dev/vda  root filesystem
scsi1 -> /dev/vdb  cloud-init data
```

Collect `qm config`, `qm showcmd --pretty`, `pvesm status`, and `PVE::Storage::parse_volname()` output when diagnosing a backend-specific format mismatch.

## No network / no guest agent / no balloon <a href="#no-network--no-guest-agent--no-balloon" id="no-network--no-guest-agent--no-balloon"></a>

Check the QEMU devices, guest character devices, and release build log rather than searching compressed `vmlinuz` strings:

```bash
qm showcmd <vmid> --pretty | grep -E 'virtio-(net|serial|balloon)'
ls -l /dev/vport* /dev/virtio-ports/*
```

A `/dev/vport*p*` character device proves that the virtio-console driver is active. Do not expect a particular number: the index follows virtio probe order, and a trixie guest on PVE 9.1.9 gets `/dev/vport2p1`. The named `/dev/virtio-ports/org.qemu.guest_agent.0` symlink additionally depends on guest udev processing and is absent on these guests even though the kernel driver works.

Since v0.3.24, generated systemd guests use one replacement unit named `qemu-guest-agent.service`. It polls for the named device and then for any `/dev/vport*p*`, and starts the packaged agent directly against the first match, avoiding the missing-symlink failure, the hardcoded-index failure, and the older competing-agent restart loop. Diagnose existing guests with:

```bash
systemctl status qemu-guest-agent.service microvm-agent.service --no-pager
ps -ef | grep '[q]emu-ga'
ls -l /dev/vport* /dev/virtio-ports/*
```

There must be exactly one `qemu-ga` process. See `docs/known-issues.md` for the existing-guest replacement unit and EL binary-path note.

The release workflow prints the final values of `CONFIG_VIRTIO_NET`, `CONFIG_VIRTIO_CONSOLE`, and `CONFIG_VIRTIO_BALLOON` after `olddefconfig`; all must be `=y`. The overlay is in `kernel/pve-microvm-overlay.config`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.layeronecloud.com/pve-microvm/troubleshooting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
