When yolo goes sideways, the issue is almost always in one of three
layers: the host (KVM, matchlock), yolo's state files, or a
provisioner script. This chapter is organized that way.
Your user can't access KVM.
ls -l /dev/kvm
# crw-rw---- 1 root kvm ... /dev/kvm
# Add yourself to the kvm group, then log out and back in:
sudo usermod -aG kvm "$USER"On WSL2, install a kernel with KVM enabled or run on bare Linux — matchlock can't run nested under most cloud VMs either.
yolo does not bundle matchlock. Install it from
matchlock's release page and ensure it's on your
PATH:
which matchlock && matchlock --versionThe /dev/kvm and matchlock requirements above apply only to the
default matchlock backend. If you can't (or don't want to) use KVM, run
with the podman backend — it needs only podman on your PATH:
which podman && podman --version
YOLO_BACKEND=podman yolo # or: yolo --backend podmanSee Backends for the capability differences.
matchlock's host networking (bridge/TAP setup) didn't initialize
correctly. Check matchlock's docs for required sysctls and module
loads (typically tun, kvm_intel or kvm_amd). Restart matchlock's
daemon if you run one.
Inspect what yolo thinks vs. what matchlock thinks:
yolo status
matchlock listIf yolo shows a vm-id that matchlock list doesn't, the bookkeeping
is stale:
yolo prune # drops dead bindingsThe next yolo will then auto-heal and recreate a fresh VM. See
architecture.md § Auto-heal for what
that algorithm checks.
Expected behaviour. matchlock has no restart for stopped VMs — yolo
treats stopped as "gone" and creates a new one (which re-runs the
provisioner). Use yolo stop deliberately, not as a "pause" button.
Either run yolo prune (drops the stale binding) or just yolo (it
will notice the VM is gone and auto-heal).
Each yolo attach (and each yolo -- CMD) is a separate
matchlock exec invocation. matchlock exec runs
your command inside the VM under a fresh PID namespace and a private
/proc mount, so sibling sessions can't see each other's processes
via ps, top, pgrep, kill, or /proc/<pid> — even when both run
as root. This is deliberate sandboxing in matchlock; it's not a yolo
limitation and there's no yolo flag to disable it.
The VM filesystem itself is shared across sessions — the workspace
(/work), $HOME, and the rest of the guest disk are the same
underlying storage. Files written in one session are immediately
visible from another; only the process view is isolated.
If you need long-running processes that survive a session and remain
reachable from later attaches, run them under a supervisor inside the
guest (for example a systemd user unit) and let each yolo shell
talk to that supervisor.
yolo duVM rootfs disks are sparse on the host but grow as the guest writes.
Common culprits: a stuck dnf cache, large build artifacts under
/root, an interrupted go install leaving partials. Drop into the VM
and clean up, or yolo rm and rebuild.
The script ran as root with your stdio attached, so the error is on
your screen. After investigating, either:
- Fix the script and re-run:
yolo provision(forces re-apply), or - Drop the VM and try fresh:
yolo rm && yolo.
yolo only re-runs the Yolofile when its body hash changes. Editing
front matter (image, cpus, memory, disk-size) is intentionally
non-triggering — those fields apply only at VM creation. To pick them
up:
yolo rm
yoloSee Yolofile reference § Re-provisioning.
yolo provision # use the resolved provisioner
yolo provision --provisioner fedora-go # specific oneIdempotent — safe to repeat.
You have YOLO_ALLOW set, so matchlock is in MITM mode and the guest
doesn't trust matchlock's ephemeral CA. See
Networking § Why TLS breaks.
Quickest fix: unset YOLO_ALLOW for normal use.
The host is allow-listed but DNS in the guest is broken. Check
/etc/resolv.conf inside the VM and verify upstream resolvers are
reachable.
yolo's state lives in $XDG_RUNTIME_DIR/yolo/ (typically
/run/user/$UID/yolo/, falling back to /tmp/yolo/ if XDG_RUNTIME_DIR
is unset):
<name>.vmid # the matchlock vm-id currently bound to this name
<name>.applied # vm-id + list of provisioners already applied to it
Full layout and semantics are in architecture.md § State files.
To nuke yolo's view of the world without touching matchlock:
rm -rf "${XDG_RUNTIME_DIR:-/tmp}/yolo"The next yolo will create a fresh VM (matchlock-side VMs you didn't
remove will leak — list them with matchlock list and clean up by
hand).
To nuke everything for a clean slate, list every named VM and remove it, then drop the local state:
yolo ls # note each NAME in the first column
yolo rm -n NAME # repeat for each one
rm -rf "${XDG_RUNTIME_DIR:-/tmp}/yolo"If none of the above applies, collect:
yolo --version
matchlock --version
uname -a
yolo status
yolo logs | tail -200…and open an issue at https://github.com/rubiojr/yolo.