Skip to content

Convert to Template Fails / Template Not Found

Three distinct symptoms, three different causes. Match the exact message in the 🔔 Alarms feed or task drawer.

Symptom 1 — [Errno 2] No such file or directory: …_tmplt.qcow2

Template failed: vm-alpine-01
[Errno 2] No such file or directory:
'/var/lib/libvirt/images/vm-alpine-01.qcow2' ->
'/var/lib/libvirt/images/vm-alpine-01_tmplt.qcow2'

Root cause

An old worker build that assumed every VM's disk lived at /var/lib/libvirt/images/<vm>.qcow2. VMs on ZFS or NFS keep their disk under the pool/mount, so the rename hit a path that didn't exist. Worse, the old code undefined the domain before the rename, so the VM was torn down even though the convert failed.

Fix

Update the worker to the convert-in-place build, which reads the real disk path from libvirt and renames it where it already lives:

  • Compute nodes: Hosts → node row → 🛠 Repair Agent (re-pushes the tasks/ tree and restarts the worker).
  • Master-as-compute: docker compose up -d --build worker beat.

Recover an already-broken VM

If you hit this on the old build, the VM's domain is gone and its inventory row was removed, but the disk still exists under its original name. On the node:

find / -xdev -name '<vm>.qcow2' 2>/dev/null
# turn it into the template you wanted:
mv <found-path> <same-dir>/<vm>_tmplt.qcow2

No data is lost — the disk was only orphaned.

Symptom 2 — TypeError: create_vm() got an unexpected keyword argument 'template_path'

Create failed: vm-01
TypeError: create_vm() got an unexpected keyword argument 'template_path'
(VM record automatically cleaned up due to failure).

Root cause

A version split: the master was updated (it dispatches deploys with the new template_path argument) but the worker that ran the task is still on the old code. The master is fine; the worker is stale.

Fix

Sync the worker that owns that deploy's queue:

  • Deploy targeted a compute nodeRepair Agent on that node.
  • Deploy targeted localhost → rebuild the worker containers, not just app:
docker compose up -d --build app worker beat
# if a cached layer kept old code:
docker compose up -d --build --force-recreate worker beat

Confirm the worker actually updated

# compute node:
ssh root@<node> "grep -n template_path /root/kvm_compute/tasks/core.py"
# master worker container:
docker compose exec worker grep -n template_path tasks/core.py

You should see template_path: str = "" in the create_vm signature. Missing = still stale.

The general rule

Anything under tasks/ is worker code. Editing it and rebuilding only app is the #1 cause of these splits — re-push to the workers (Repair Agent for nodes, rebuild worker/beat for localhost).

Symptom 3 — No local file-backed disk found … Ceph/LINSTOR not supported

No local file-backed disk found for this VM — only local/ZFS/NFS
qcow2 disks convert to a template (Ceph/LINSTOR not supported). VM left intact.

This is expected, not a bug

The VM's disk is on a network backend (Ceph RBD or LINSTOR/DRBD) with no local file to rename. The convert refuses before touching the domain, so the VM keeps running and stays in inventory. Build your golden source on a local / ZFS / NFS VM instead.

Symptom 4 — Template doesn't appear in the Deploy dialog

Templates are node-local. The Deploy dialog lists templates for the host selected in its Host field.

  • Switch Host to the node where you ran the conversion.
  • To use it elsewhere, scp the <vm>_tmplt.qcow2 to the other node first, then it shows up for that host.

See also