| Tested on | Rocky Linux 10.2 (Red Quartz) |
|---|---|
| Package | virt-install 5.1.0libvirt 11.10.0qemu-kvm 10.1.0 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Ubuntu, Debian |
| Privilege | sudo or root |
| Man page | virt-install(1) |
| Scope | Provision KVM guests from ISO, HTTP install trees, PXE, or imported disks — CPU, memory, storage, networking, console, and autostart options. |
| Related guides | Install KVM on RHEL/CentOS 8 Create KVM VM with Cockpit KVM PXE netboot Create KVM VM with Virtual Manager Linux commands |
virt-install — quick reference
Guest sizing and identity
| When to use | Command |
|---|---|
| Set guest name (must be unique on the host) | virt-install --name VMNAME ... |
| Allocate RAM in MiB | virt-install --memory 4096 ... |
| Set vCPU count | virt-install --vcpus 4 ... |
| Pick OS profile for defaults | virt-install --osinfo rocky10 ... |
| Connect to system libvirt (KVM default) | virt-install --connect qemu:///system ... |
Install media
| When to use | Command |
|---|---|
| Install from local ISO | virt-install --cdrom /path/to.iso ... |
| Install from distro tree or mirror URL | virt-install --location http://mirror/... ... |
| Boot from PXE (network must reach DHCP/TFTP/iPXE) | virt-install --pxe --network bridge=br0 ... |
| Skip install — boot an existing disk image | virt-install --import --disk path=/path/to.img ... |
| Install using the URL and defaults from a libosinfo profile | virt-install --install rocky10 ... |
Storage
| When to use | Command |
|---|---|
| Create a qcow2 disk in the default pool | virt-install --disk size=20 ... |
| Create a volume in a custom libvirt pool | virt-install --disk pool=vm-disks,size=40,format=qcow2 ... |
| Custom path, size, and format | virt-install --disk path=/disks/vm.qcow2,size=20,format=qcow2 ... |
| Attach multiple disks | virt-install --disk size=20 --disk path=/disks/data.qcow2,size=50 ... |
Network
| When to use | Command |
|---|---|
| Attach the libvirt default NAT network | virt-install --network network=default ... |
| Bridge to a host bridge | virt-install --network bridge=br0 ... |
| Add a second NIC | virt-install --network network=default --network bridge=br0 ... |
Console and graphics
| When to use | Command |
|---|---|
| Enable a graphical VNC console | virt-install --graphics vnc ... |
| Headless serial console only | virt-install --graphics none --console pty,target_type=serial ... |
| Detach from the console and return quickly | virt-install --noautoconsole ... |
| Keep a detached install alive through reboot | virt-install --noautoconsole --wait -1 ... |
Pass kernel args (with --location) |
virt-install --extra-args "console=ttyS0" ... |
Post-install behavior
| When to use | Command |
|---|---|
| Mark the guest to start on host boot | virt-install --autostart ... |
| Preview domain XML without defining the VM | virt-install --dry-run --print-xml ... |
| Unattended OS install (distro-dependent) | virt-install --unattended ... |
virt-install — command syntax
virt-install creates guests through libvirt. On a KVM host you normally target the system hypervisor with --connect qemu:///system. Synopsis from virt-install --help on Rocky Linux 10.2 (virt-install 5.1.0):
virt-install OPTIONS
Create a new virtual machine from specified install media.
General Options:
-n NAME, --name NAME Name of the guest instance
--memory MEMORY Configure guest memory allocation (MiB)
--vcpus VCPUS Number of vCPUs to configure
--cpu CPU CPU model and features
Installation Method Options:
--cdrom CDROM CD-ROM installation media
-l LOCATION, --location LOCATION
Distro install URL or local tree
--pxe Boot from the network using PXE
--import Build guest around an existing disk image
--install INSTALL Specify fine grained install optionsMinimum inputs for a manual install are typically --memory, guest storage (--disk or --filesystem), an install method (--cdrom, --location, --pxe, --import, or --install), and --osinfo when detection cannot run. The graphics default is adaptive — virt-install may choose SPICE, VNC, or no graphics depending on environment; pass --graphics vnc explicitly when you need VNC. Install and enable KVM on the host before running these examples.
virt-install — command examples
Essential Check version and list OS profiles
Confirm virt-install is installed and see which --osinfo values libosinfo knows on your host.
Run the command:
virt-install --versionSample output:
5.1.0List short OS IDs you can pass to --osinfo:
virt-install --osinfo list | head -8Sample output:
almalinux10
almalinux9
almalinux8
almalinux-kitten10
alpinelinux3.23
alpinelinux3.22
alpinelinux3.21
alpinelinux3.20Use osinfo-query os for the full table with distro names and versions.
Essential List libvirt networks before attaching one
virt-install references network names defined in libvirt — usually default on a fresh KVM host.
Run the command:
virsh net-list --allSample output:
Name State Autostart Persistent
--------------------------------------------
default active yes yesPass network=default to attach the NAT network, or bridge=br0 when the guest should share a host bridge.
If default is missing or inactive on RHEL-family hosts:
sudo virsh net-autostart default
sudo virsh net-start defaultWhen the network does not exist, verify or reinstall libvirt-daemon-config-network.
Essential Preview domain XML with --dry-run
--dry-run --print-xml validates options and prints libvirt XML without defining the guest. Include the same install method (--cdrom, --location, --pxe, --import, or --install) you plan to use — --dry-run skips changes but still runs normal validation. With --location, virt-install may fetch installation metadata or boot files for OS detection.
Run the command:
virt-install --connect qemu:///system \
--dry-run --print-xml \
--name demo-test \
--memory 2048 --vcpus 2 \
--osinfo rocky10 \
--location https://download.rockylinux.org/pub/rocky/10/BaseOS/x86_64/os/ \
--disk size=5,format=qcow2 \
--network network=default \
--graphics vnc \
--noautoconsoleSample output:
<domain type="kvm">
<name>demo-test</name>
<memory>2097152</memory>
<vcpu>2</vcpu>
<os>
<type arch="x86_64" machine="q35">hvm</type>
</os>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" discard="unmap"/>
<source file="/var/lib/libvirt/images/demo-test.qcow2"/>
<target dev="vda" bus="virtio"/>
</disk>On a KVM-capable host the root element is normally <domain type="kvm">. If you see type="qemu", the host is falling back to software emulation — enable hardware virtualization in firmware and confirm the kvm module is loaded.
If the default storage pool is too small, shrink --disk size= or free space under /var/lib/libvirt/images/.
Common Install from a local ISO with VNC graphics
Match --osinfo to the OS on the ISO — Rocky media needs rocky10, not an RHEL profile. Linux paths are case-sensitive; use the exact filename on your host.
Run the command:
sudo virt-install --connect qemu:///system \
--name rocky10-guest \
--memory 4096 --vcpus 2 \
--osinfo rocky10 \
--cdrom /var/isos/Rocky-10.2-x86_64-dvd.iso \
--disk size=20,format=qcow2 \
--network network=default \
--graphics vnc \
--console pty,target_type=serialVNC commonly listens on 127.0.0.1 only. Find the display with virsh vncdisplay rocky10-guest, then connect through local virt-viewer, an SSH tunnel, or a libvirt connection over SSH — you do not need to expose VNC publicly. --cdrom boots the ISO; use --location when virt-install should fetch kernel/initrd and start the installer automatically.
Common Install from an HTTP mirror with --location
--location points at a distro install tree. virt-install pulls vmlinuz and initrd, then hands off to the network installer.
Run the command:
sudo virt-install --connect qemu:///system \
--name rocky10-netinst \
--memory 2048 --vcpus 2 \
--osinfo rocky10 \
--location https://download.rockylinux.org/pub/rocky/10/BaseOS/x86_64/os/ \
--disk size=10 \
--network network=default \
--graphics vnc --noautoconsoleUse a mirror URL that matches your architecture. For kickstart, point inst.ks= at an HTTP, HTTPS, NFS, or other installer-accessible URL:
--extra-args "inst.ks=https://server.example.com/kickstart/rocky10.cfg"Or inject a host-local file into the installer initrd:
--initrd-inject /path/to/rocky10.cfg \
--extra-args "inst.ks=file:/rocky10.cfg"Confirm the profile exists locally with virt-install --osinfo list before using --install rocky10 — an older osinfo database can lack newer distributions even when virt-install supports --install.
Common Place disks in a libvirt storage pool
RHEL-family hosts recommend file-backed disks as volumes in a directory storage pool. /var/lib/libvirt/images is labeled for libvirt by default; custom paths need equivalent SELinux/sVirt handling — changing ownership to qemu alone may not fix access.
Define a pool, then reference it from virt-install:
sudo mkdir -p /disks
sudo virsh pool-define-as vm-disks dir --target /disks
sudo virsh pool-start vm-disks
sudo virsh pool-autostart vm-disksRun the command:
sudo virt-install --connect qemu:///system \
--name app-vm \
--memory 8192 --vcpus 4 \
--osinfo rocky10 \
--cdrom /var/isos/Rocky-10.2-x86_64-dvd.iso \
--disk pool=vm-disks,size=40,format=qcow2 \
--network bridge=br0 \
--graphics vnc --autostart--autostart marks the persistent domain to start automatically during host boot. When you must use a raw path=, verify parent-directory traversal, libvirt/QEMU permissions, and SELinux contexts — not just Unix ownership.
Common Attach multiple network interfaces
Repeat --network for each NIC. Mix NAT and bridged attachments when the guest needs management and data-plane separation.
Run the command:
sudo virt-install --connect qemu:///system \
--name dual-nic-vm \
--memory 4096 --vcpus 2 \
--osinfo rocky10 \
--location https://download.rockylinux.org/pub/rocky/10/BaseOS/x86_64/os/ \
--disk size=20 \
--network network=default \
--network bridge=br0 \
--graphics vnc --console pty,target_type=serialList host bridges with ip link show type bridge before choosing bridge=.
Advanced Detach after kickoff with --noautoconsole
When you launch from SSH, --noautoconsole returns control immediately. Finish the install through VNC or virsh console.
Run the command:
sudo virt-install --connect qemu:///system \
--name headless-install \
--memory 2048 --vcpus 2 \
--osinfo rocky10 \
--location https://download.rockylinux.org/pub/rocky/10/BaseOS/x86_64/os/ \
--disk size=10 \
--network network=default \
--graphics none \
--console pty,target_type=serial \
--extra-args "console=ttyS0" \
--noautoconsoleSample output:
Domain installation still in progress. You can reconnect to
the console to complete the installation process.Reconnect with virsh console headless-install. Press Ctrl+] to leave the serial session.
--noautoconsole detaches virt-install from the console and normally lets the command exit quickly. For a multi-stage --location or --cdrom install, the guest may be left shut off when installation completes. Start it with virsh start headless-install, or add --wait -1 when you want virt-install to remain running through the post-install reboot.
Advanced Import an existing disk image with --import
Skip the installer when you already have a configured bootable disk image or clone — not a generic cloud image that still needs cloud-init credentials.
Run the command:
sudo virt-install --connect qemu:///system \
--name imported-vm \
--memory 2048 --vcpus 2 \
--import \
--disk path=/var/lib/libvirt/images/existing.qcow2,format=qcow2 \
--osinfo rocky10 \
--network network=default \
--graphics vnc --noautoconsoleThe disk file must exist before you run the command. The new domain name must be unique — no virsh undefine is required when importing under a different name. When reusing an existing domain name, shut down and undefine that domain deliberately, and confirm whether its storage or UEFI NVRAM must be retained.
For cloud images that ship without a local login, add --cloud-init (optionally with root-ssh-key=, clouduser-ssh-key=, or user-data=). Plain --cloud-init creates temporary NoCloud metadata, generates a root password, prints it, and disables cloud-init after the first boot.
Advanced Network install with --pxe
--pxe configures network boot for the first boot only. The selected network must reach DHCP, TFTP/iPXE, and boot configuration — use a host bridge when your PXE server lives on the physical LAN. inst.ks= belongs in the PXE boot entry the server serves, not in --extra-args (that flag is for --location installs).
Run the command:
sudo virt-install --connect qemu:///system \
--name pxe-guest \
--memory 4096 --vcpus 2 \
--osinfo rocky10 \
--pxe \
--disk size=20 \
--network bridge=br0 \
--graphics vnc \
--console pty,target_type=serialUse network=default only when that libvirt network is configured to provide or forward PXE services. See KVM PXE netboot for the full server setup.
virt-install — when to use / when not
| Use virt-install when | Use something else when |
|---|---|
| You need a scriptable, repeatable VM create from SSH | You prefer a GUI — Cockpit or virt-manager |
You automate installs with kickstart, cloud-init, or --unattended |
You only need to start/stop existing guests — virsh |
| You want explicit control over every disk, NIC, and console flag in one command | You manage VMs at scale with oVirt, OpenStack, or a cloud API |
| You provision from ISO, HTTP tree, or PXE in one step | The host does not have KVM/libvirt installed yet — install the stack first |
virt-install vs Cockpit / virt-manager
| virt-install | Cockpit / virt-manager | |
|---|---|---|
| Interface | CLI flags and scripts | Web UI or desktop GUI |
| Automation | Easy in shell, Ansible, CI | Manual clicks; limited scripting |
| Preview | --dry-run --print-xml |
Visual wizard |
| Learning curve | Must know libvirt options | Discover options in forms |
| Typical use | Servers, kickstart farms, docs-as-code | Ad-hoc lab VMs |
Many teams use virt-install (or virt-install --install DISTRO) in scripts and fall back to Cockpit for one-off troubleshooting.
virt-install — interview corner
What does virt-install do?
virt-install is the libvirt CLI tool that creates new virtual machines — it defines CPU, memory, disks, networks, and install media, then either launches an interactive installer or imports an existing disk.
A strong answer is:
"virt-install talks to libvirt to define a KVM guest and attach install media — ISO, URL, PXE, or an imported disk — with the console and storage layout I specify."
What is the difference between --cdrom and --location?
| Flag | Behavior |
|---|---|
--cdrom /path/to.iso |
Attaches ISO as virtual CD — guest boots installer media |
--location URL or path |
Fetches kernel/initrd from an install tree and often starts the installer automatically |
Use --location for HTTP/FTP mirrors; use --cdrom for a single ISO file on disk.
A strong answer is:
"--cdrom mounts an ISO; --location points at a distro tree and virt-install pulls boot files — better for network-based installs."
Why use --osinfo?
--osinfo (formerly --os-variant) selects a libosinfo profile so virt-install picks sensible defaults: chipset, disk bus, clock, and supported install methods for that OS.
Run virt-install --osinfo list or osinfo-query os on the host to see valid IDs.
A strong answer is:
"--osinfo tells virt-install which OS I'm installing so it applies the right virtio defaults and avoids misconfigured guests."
When would you use --noautoconsole?
Use --noautoconsole when you start a long install over SSH and do not want virt-install to hold the terminal until the installer finishes. You reconnect with VNC (virsh vncdisplay VMNAME) or virsh console.
For multi-stage --cdrom or --location installs, the guest may shut off when installation completes unless you add --wait -1 to keep virt-install running through the post-install reboot.
Pair with --graphics vnc for graphical installs, or --graphics none --extra-args "console=ttyS0" for serial-only.
A strong answer is:
"--noautoconsole returns the shell quickly; I finish through VNC or virsh console, and I use --wait -1 when I need virt-install to survive the install-to-reboot transition."
How do you validate a virt-install command before creating a VM?
Run the same flags with --dry-run and --print-xml, including the install method (--cdrom, --location, --pxe, --import, or --install). virt-install may still fetch metadata for --location installs even in dry-run mode.
A strong answer is:
"I dry-run with --print-xml and the same install source to verify disks, networks, and OS profile before defining the guest."
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
failed to connect to the hypervisor |
Modular libvirt sockets not running, insufficient privileges, or wrong URI (EL10) | Start virt*d sockets: for drv in qemu network nodedev nwfilter secret storage interface; do sudo systemctl start virt${drv}d{,-ro,-admin}.socket; done; verify virsh -c qemu:///system list --all; confirm root or libvirt group access |
| Same error on older distributions | Monolithic libvirt service stopped | sudo systemctl start libvirtd on releases that still use libvirtd.service; use --connect qemu:///system |
cannot find network: default |
Default libvirt network missing or inactive | sudo virsh net-autostart default; sudo virsh net-start default; verify libvirt-daemon-config-network |
KVM acceleration not available |
CPU virtualization off or nested virt missing | Enable VT-x/AMD-V in firmware; load kvm module |
exceed the available pool space |
Default pool too small for --disk size= |
Free space under /var/lib/libvirt/images/ or use a larger storage pool |
Validating install media ... failed |
Wrong ISO/tree path | Fix path; for trees use --location, for ISO use --cdrom |
Stuck at Escape character is ^] |
--graphics none without serial console setup |
Add --console pty,target_type=serial and --extra-args "console=ttyS0", or use --graphics vnc |
Active console session exists |
Another virsh console still attached |
Exit with Ctrl+] or close the other session |
| OS detection failed | Missing or unknown install media | Set --osinfo NAME explicitly from virt-install --osinfo list |
| Guest not autostarting on host reboot | --autostart not set |
virsh autostart VMNAME or recreate with --autostart |
<domain type="qemu"> in XML preview |
Software emulation fallback | Enable KVM in firmware; confirm /dev/kvm and kvm module on the host |

