Installing the Vagrant libvirt Provider on Ubuntu 22.04 LTS

Vagrant ships with VirtualBox as its default provider, but on Linux KVM/libvirt is the better fit: it’s the kernel’s native hypervisor, it’s faster, and it doesn’t require an out-of-tree kernel module. The bridge between the two is vagrant-libvirt, a Vagrant plugin that drives libvirt instead of VirtualBox.

This post walks through the full setup on Ubuntu 22.04 LTS (Desktop or Server). It is largely a distillation of Paul Neumann’s gist, which itself builds on Philippe Vanhaesendonck’s Oracle Linux write-up — kept here for my own reference and slightly reorganized.


Prerequisites

Hardware virtualization support

KVM is a Type-1-style hypervisor that relies on CPU virtualization extensions (Intel VT-x or AMD-V). Check that your CPU exposes them:

grep -E -c '(vmx|svm)' /proc/cpuinfo

Anything >= 1 is fine. A 0 means either the CPU does not support virtualization or — much more commonly — it is disabled in the BIOS/UEFI. Reboot into firmware settings and toggle “Intel VT-x”, “AMD-V”, or “SVM” before going further.

System up to date

sudo apt-get -y update && sudo apt-get -y upgrade

Password-less sudo (optional but practical)

vagrant-libvirt configures NFS shares as root every time you vagrant up or vagrant halt. Without password-less sudo, you’ll be prompted for your password on every guest lifecycle event — quickly tedious during iterative work.

sudo su -c "echo \"$(id -un) ALL=(ALL) NOPASSWD: ALL\" > /etc/sudoers.d/$(id -un)"
sudo su -c "chmod 0440 /etc/sudoers.d/$(id -un)"

⚠️ Password-less sudo is a real reduction in your local security posture. Apply it on a dev workstation, not on a shared or production host.


Install KVM and libvirt

Core packages

sudo apt-get -y install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils
sudo systemctl enable --now libvirtd

What each package does:

  • qemu-kvm — the userspace emulator integrated with the KVM kernel module.
  • libvirt-daemon-system / libvirt-clients — the libvirt API daemon and virsh CLI.
  • bridge-utils — utilities to manage the network bridge that VMs use.

On a Desktop install, the GUI manager is also worth having for troubleshooting:

sudo apt-get -y install virt-manager

Add yourself to the right groups

Your user needs to belong to libvirt and kvm to drive the hypervisor without sudo:

sudo adduser "$(id -un)" libvirt
sudo adduser "$(id -un)" kvm

⚠️ Group membership only takes effect on a fresh login session. Log out and log back in (or reboot) before continuing — this trips up everyone the first time.

Sanity check

virsh list --all

Expected output (no VMs yet, but the daemon answers):

 Id   Name   State
--------------------

A connection error here means either the daemon is not running, or your user is not in the libvirt group, or you forgot to re-login.


Install Vagrant

The Ubuntu archive’s Vagrant lags upstream considerably. HashiCorp’s APT repository is the better source:

wget -O- https://apt.releases.hashicorp.com/gpg | \
  sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
  https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/hashicorp.list

sudo apt update && sudo apt install vagrant

Verify:

vagrant --version
# Vagrant 2.3.7

Install the vagrant-libvirt plugin

The plugin is a native Ruby gem that builds against libvirt and libxml2 at install time. Three steps: enable Ubuntu’s source repositories, install build dependencies, install the plugin.

Enable universe source repositories

vagrant-libvirt pulls in ruby-libvirt build deps that come from the universe source repo, which is disabled by default on Ubuntu 22.04. Enable it (after a backup of sources.list):

sudo cp /etc/apt/sources.list /etc/apt/sources.list."$(date +"%F")"
sudo sed -i -e '/^# deb-src.*universe$/s/# //g' /etc/apt/sources.list
sudo apt-get -y update

Install build and runtime prerequisites

# NFS server — used for synced folders
sudo apt-get -y install nfs-kernel-server
sudo systemctl enable --now nfs-server

# Build dependencies for vagrant and ruby-libvirt
sudo apt-get -y build-dep vagrant ruby-libvirt

# Networking helpers used by libvirt's default network
sudo apt-get -y install ebtables dnsmasq-base

# Headers needed to compile the plugin's native extensions
sudo apt-get -y install libxslt-dev libxml2-dev libvirt-dev zlib1g-dev ruby-dev

Install the plugin itself

vagrant plugin install vagrant-libvirt

This step compiles the native extensions and is the most likely point of failure. If it errors out, the message almost always points at a missing *-dev package — install it and re-run.

Confirm it’s loaded:

vagrant plugin list
# vagrant-libvirt (0.12.x, global)

First Test

A minimal Vagrantfile to validate the stack end to end:

Vagrant.configure("2") do |config|
  config.vm.box = "generic/ubuntu2204"
  config.vm.provider :libvirt do |libvirt|
    libvirt.cpus   = 2
    libvirt.memory = 2048
  end
end

Then:

vagrant up --provider=libvirt
vagrant ssh

If you want libvirt to be the default provider so you don’t have to pass --provider every time:

echo 'export VAGRANT_DEFAULT_PROVIDER=libvirt' >> ~/.bashrc

Boxes flagged with libvirt support live in Vagrant Cloud. The generic/* family by Roboxes covers most common distributions.


Common Pitfalls

  • Call to virDomainCreateWithFlags failed: internal error: Network 'default' is not active — the libvirt default network is not started. Fix with sudo virsh net-start default && sudo virsh net-autostart default.
  • NFS prompts for a password every time — you skipped the password-less sudo step, or you applied it to a different user than the one running vagrant.
  • vagrant plugin install fails compiling native extensions — almost always a missing *-dev header package; re-read the error and install what it asks for.
  • Group changes don’t take effect — you didn’t fully log out. SSH sessions, screen/tmux sessions, and graphical sessions all need to be restarted to inherit the new group membership.

Recap

The minimal happy path:

  1. Verify CPU virtualization support and update the system.
  2. (Optional) Enable password-less sudo for the user running Vagrant.
  3. Install qemu-kvm, libvirt-daemon-system, libvirt-clients, bridge-utils; enable libvirtd.
  4. Add the user to libvirt and kvm, then log out and back in.
  5. Install Vagrant from HashiCorp’s APT repo.
  6. Enable universe source repos, install plugin build dependencies, install nfs-kernel-server.
  7. vagrant plugin install vagrant-libvirt.
  8. Test with a minimal Vagrantfile and vagrant up --provider=libvirt.

Once set up, the libvirt provider is noticeably faster than VirtualBox for daily Vagrant work and integrates cleanly with the rest of the libvirt ecosystem (virsh, virt-manager, libvirt networks, storage pools).