Open virt-manager as a regular user on a fresh KVM host and it stops at “authentication unavailable: no polkit agent available to authenticate action ‘org.libvirt.unix.manage'”. That’s libvirt refusing a user it doesn’t trust, and on current distros one command clears it, adding the user to the libvirt group. You do not need to edit libvirtd.conf, change socket permissions or run virt-manager with sudo.
Below, we add a user to the libvirt group, explain the polkit rule behind it and fix the two things that still break afterwards. Those are the modular daemon sockets on Rocky Linux and the qemu:///session default that hides your VMs from virsh. The group, socket and URI steps were run as a normal user on Rocky Linux 10 (libvirt 11.10) and Debian 13 (libvirt 11.3) in October 2026, ending with a test VM created without sudo. The virt-manager screenshots are from the Debian host.
Install KVM and virt-manager
The permission fix only matters once the hypervisor stack is in place, so get these on the host first:
- A CPU with virtualization enabled, so
/dev/kvmexists - libvirt and QEMU from the distro repositories
- virt-manager (CRB on Rocky Linux 10, main archive on Debian 13)
- A regular user that can run sudo for the one-time setup
If the host is not set up yet, the full KVM install on Rocky Linux covers CPU checks and bridging. The short version is below. The two distros differ in ways that show up later in this guide (daemon layout, default network, /dev/kvm mode), so it pays to know which one you are on before you start chasing errors.
On Rocky Linux 10, libvirt and qemu-kvm come from AppStream but virt-manager sits in the CRB repository. Check where dnf finds it before you install:
dnf -q list virt-manager
dnf -q list libvirt-daemon-kvm qemu-kvm
The last column is the repository. Ours showed crb for virt-manager and appstream for the rest:
Available Packages
virt-manager.noarch 5.1.0-2.el10 crb
Available Packages
libvirt-daemon-kvm.x86_64 11.10.0-12.9.el10_2 appstream
qemu-kvm.x86_64 18:10.1.0-16.el10_2.5 appstream
If virt-manager does not appear at all, CRB is disabled on your box, and the steps to enable the CRB repository take a minute. Then install the stack and start the QEMU driver socket:
sudo dnf -y install qemu-kvm libvirt virt-manager virt-install
sudo systemctl enable --now virtqemud.socket
Rocky uses the modular daemons, so there is no libvirtd running at all. The QEMU driver has its own daemon, virtqemud, started on demand by that socket. A quick check confirms the packages and shows the socket virt-manager will talk to.
rpm -q libvirt virt-manager
ls -l /run/libvirt/virtqemud-sock
The socket is mode 0666, which surprises people who expect it to be locked down. File permissions are not what keeps regular users out here. polkit is, which is why the old advice to edit socket permissions does nothing on a current install.
libvirt-11.10.0-12.9.el10_2.x86_64
virt-manager-5.1.0-2.el10.noarch
srw-rw-rw-. 1 root root 0 Oct 18 03:58 /run/libvirt/virtqemud-sock
On Debian 13 everything is in the main archive. The lab VM was headless, so we installed without recommends and added the SPICE client library virt-manager needs for its console window. On a desktop install you can drop --no-install-recommends, and the Debian KVM setup with Cockpit covers the rest of the host:
sudo apt-get install -y --no-install-recommends qemu-system-x86 libvirt-daemon-system virt-manager gir1.2-spiceclientgtk-3.0
Debian still starts the monolithic libvirtd, and its socket has the same 0666 mode. Note the /dev/kvm line as well, because it comes up again in the troubleshooting section:
systemctl is-active libvirtd virtqemud
ls -l /run/libvirt/libvirt-sock /dev/kvm
Here libvirtd is active and virtqemud is not, which is the reverse of Rocky:
active
inactive
crw-rw---- 1 root kvm 10, 232 Oct 18 04:00 /dev/kvm
srw-rw-rw- 1 root root 0 Oct 18 04:00 /run/libvirt/libvirt-sock
Those differences are easier to keep straight side by side. Everything in this table came from the two lab hosts, read with the same commands shown above.
| Item | Rocky Linux 10 | Debian 13 |
|---|---|---|
| libvirt version | 11.10.0 | 11.3.0 |
| virt-manager version | 5.1.0 (CRB repo) | 5.0.0 (main) |
| Daemon model | Modular (virtqemud, virtnetworkd…) | Monolithic libvirtd |
| polkit rule file | /usr/share/polkit-1/rules.d/50-libvirt.rules | /usr/share/polkit-1/rules.d/60-libvirt.rules |
| libvirt group GID | 989 | 105 |
| /dev/kvm mode | 0666 | 0660, group kvm |
| Default network after install | Active, autostart | Inactive, no autostart |
The rows that bite are the daemon model and the default network. On Rocky the group fix alone leaves networks and storage pools unreachable, because their daemons have no sockets yet. On Debian the network exists but sits inactive, so a new VM has nothing to attach to until you start it. Both get their own step below, and the polkit rule file name is the only other difference you are likely to look up.
Reproduce the polkit error
Before changing anything, confirm you are hitting the polkit check and not something else, because a missing daemon or the wrong URI fails with a different message and needs a different fix. Run virsh against the system instance as your normal user. We used a user called josphat with no extra groups.
virsh -c qemu:///system list --all
Both distros print the same two lines, word for word, so the cause and the fix are the same on both.
error: failed to connect to the hypervisor
error: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'
The message is literal. polkit wanted to ask for an admin password and found no agent to ask through, since an SSH session or a bare X session has none. With nobody to prompt, it denied the request. virt-manager hits the same wall and shows it as a connection failure, with the QEMU/KVM entry stuck on “Not Connected”:

On a full desktop with a polkit agent running, the libvirt docs say you get an admin password prompt instead of this dialog, and the default auth_admin_keep policy only remembers it for that session. We didn’t run a desktop agent, so we haven’t seen the prompt ourselves. Either way the password comes back in every new session, which is the annoyance this guide removes.
Add user to libvirt group
Both distros ship a polkit rule that says yes to org.libvirt.unix.manage for any member of the libvirt group. You do not write this rule, you only need to be in the group. Read the Rocky copy first, since Debian’s 60-libvirt.rules is identical apart from the file name.
cat /usr/share/polkit-1/rules.d/50-libvirt.rules
The rule checks two things, the action ID and the group, and returns YES without a password prompt when both match.
// Allow any user in the 'libvirt' group to connect to system libvirtd
// without entering a password.
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.unix.manage" &&
subject.isInGroup("libvirt")) {
return polkit.Result.YES;
}
});
The group already exists after the package install (GID 989 on Rocky, 105 on Debian), so there’s no groupadd step. Add your user with usermod, and keep the -a, because -G on its own replaces every supplementary group the user has, including wheel or sudo:
sudo usermod -aG libvirt josphat
Now retry the same virsh command in the same terminal. Do not log out first, because the next result is the interesting part.
virsh -c qemu:///system list --all
It connects straight away and prints an empty VM table. Empty is correct, since no VMs exist yet, and what matters is that the polkit error is gone.
Id Name State
--------------------
That worked even though id -nG in the same shell still listed only josphat. polkit looks up the user’s groups from the system database when the request arrives, not from the groups your shell started with. The new membership counted immediately on both Rocky and Debian. The newgrp libvirt step in older guides isn’t needed for libvirt access. You’ll still want a fresh login before anything else that checks your process groups, and a new login on Rocky showed josphat libvirt as expected. The Rocky host, before and after:

Treat the group like sudo. The libvirt authentication docs compare the default polkit check to sudo, and this rule skips that password check entirely. A member can define a VM that attaches any disk or device on the host, so add the people who already administer the box and nobody else. On a shared workstation we’d rather leave a second user on the password prompt than hand them the group, because the prompt is the only thing standing between that account and the host’s disks.
The old libvirtd.conf edits are also unnecessary. On Debian the file still ships with unix_sock_group, unix_sock_rw_perms and auth_unix_rw = "polkit" commented out, which means polkit is the default and the group rule above is what grants access:
grep -E "^#?unix_sock_(group|rw_perms|ro_perms)|^#?auth_unix_rw" /etc/libvirt/libvirtd.conf
All four lines are still commented, and we left them that way for every test in this guide.
#unix_sock_group = "libvirt"
#unix_sock_ro_perms = "0777"
#unix_sock_rw_perms = "0770"
#auth_unix_rw = "polkit"
Uncommenting them adds nothing for group members. unix_sock_group with 0770 permissions changes the socket to root:libvirt mode 0770, so users outside the group get a socket permission error instead of the polkit message. You also carry one more edited config file through libvirt updates. Leave the file at its defaults and let the group do the work.
Enable the modular libvirt sockets on Rocky Linux
On Rocky the group fix gets you VM access but not networks or storage. After a fresh login, list worked while the network and pool commands failed, because only virtqemud.socket had been started:
virsh -c qemu:///system net-list --all
virsh -c qemu:///system pool-list --all
Each driver has its own daemon on Rocky, and the missing socket file is the giveaway. The EL10 preset already enables these sockets, so they come up on the next boot. They just aren’t started yet on a host you installed without rebooting, and the --now in the loop below starts them immediately.
error: Failed to list networks
error: Failed to connect socket to '/var/run/libvirt/virtnetworkd-sock': No such file or directory
error: Failed to list pools
error: Failed to connect socket to '/var/run/libvirt/virtstoraged-sock': No such file or directory
virt-manager needs the network and storage drivers to create a VM, so enable the full set of sockets the libvirt modular daemon docs describe. Each driver gets three sockets, and systemd starts the daemon behind them on the first connection:
virt<driver>d.socketfor read-write clients such as virt-managervirt<driver>d-ro.socketfor read-only clientsvirt<driver>d-admin.socketfor the daemon admin interface
The loop enables all three for every driver in one pass. It is safe to rerun, because enabling a socket that is already active changes nothing:
for drv in qemu network nodedev nwfilter secret storage interface; do sudo systemctl enable --now virt${drv}d.socket virt${drv}d-ro.socket virt${drv}d-admin.socket; done
List the active driver sockets to check that nothing was skipped.
systemctl list-units "virt*d.socket" --no-legend --plain | awk "{print \$1, \$3}"
You want to see all seven drivers plus the lock and log sockets, every one active:
virtinterfaced.socket active
virtlockd.socket active
virtlogd.socket active
virtnetworkd.socket active
virtnodedevd.socket active
virtnwfilterd.socket active
virtqemud.socket active
virtsecretd.socket active
virtstoraged.socket active
A missing line here means that driver will fail later with the same “No such file or directory” error, so rerun the loop rather than enabling sockets one at a time. Debian skips this step because libvirtd serves every driver from one daemon, and its network and pool commands worked as soon as the user joined the group.
Start the default network and storage pool
Neither lab host had a storage pool defined, and Debian’s default network was inactive with autostart off. Creating them from the shell as your normal user is also a good test, because it proves the group grants write access and not only read access. Start the network and mark it to come up at boot:
virsh -c qemu:///system net-start default
virsh -c qemu:///system net-autostart default
On Debian the autostart line confirms the change. On Rocky the network was already running, so net-start prints “network is already active”, which is harmless:
Network default marked as autostarted
Next, define a directory pool on the standard images path, start it and set it to autostart. /var/lib/libvirt/images is the default image path the packages create. Pointing the pool anywhere else adds directory and permission work you do not need for a test.
virsh -c qemu:///system pool-define-as default dir --target /var/lib/libvirt/images
virsh -c qemu:///system pool-start default
virsh -c qemu:///system pool-autostart default
Each command answers with one line, and none of them asked for a password.
Pool default defined
Pool default started
Pool default marked as autostarted
The pool and the network now come up with the host. We rebooted the Rocky host to confirm it. As the regular user, net-list showed default active with autostart on and pool-list showed the pool active. virtnetworkd and virtstoraged were running too, started by the virsh call through their sockets. Any VM you create next has somewhere to keep its disks and a NAT network to join. We ran every one of these commands as the regular user, which is the check that matters: a group that only granted read access would have failed at pool-define-as.
Create a test VM without sudo
The real proof is a running VM owned by the system instance and created by a user with no sudo in the command. Create a 2 GB volume in the pool, then import it as a small guest. The disk is empty, so the guest boots to nothing. It exists only to show the permissions work end to end:
virsh -c qemu:///system vol-create-as default web-test.qcow2 2G --format qcow2
virt-install --connect qemu:///system --name web-test --memory 256 --vcpus 1 --disk vol=default/web-test.qcow2 --import --os-variant generic --network network=default --graphics vnc --noautoconsole
virt-install reports success right away (Rocky’s run printed the same lines). With an empty disk and --import there is no installer to wait for, so the domain is defined and started in one step.
Vol web-test.qcow2 created
Starting install...
Creating domain... | 00:00
Domain creation completed.
Open virt-manager again. It connects to QEMU/KVM without a prompt and lists web-test as running, which means the group covers the GUI the same way it covers virsh. The Rocky run, with a guest called test01 and --graphics none, ended the same way in virsh: test01 running. This is the Debian host:

From here the GUI works like it does for root. Our walkthrough on how to create a Linux VM in virt-manager picks up at this point, and you can delete web-test once you have a real guest. Nothing we ran after this point needed sudo, and the connection failures we did hit are all in the error list at the end of this guide.
Make virsh default to qemu:///system
virt-manager connects to qemu:///system, but plain virsh run as a non-root user connects to qemu:///session, a separate per-user libvirt instance with its own VM list. That is why virsh list --all can come back empty while virt-manager shows a running VM. Check which URI you get.
virsh uri
On both hosts it printed the session URI, even after the user joined the libvirt group. The group changes what you are allowed to reach, not where virsh connects by default.
qemu:///session
Typing -c qemu:///system on every command gets old. Set the default in your user’s libvirt client config instead. It only affects your account, so other users and root keep their own defaults.
mkdir -p ~/.config/libvirt
echo "uri_default = \"qemu:///system\"" > ~/.config/libvirt/libvirt.conf
Now plain virsh lands on the system instance and sees the VM virt-manager created.

With the default set, every command in the virsh cheat sheet works as written, without sudo and without the -c flag.
Fix libvirt permission errors
These are the errors we hit on the two lab hosts, with the cause and the fix for each. Most people land here with the first one, and the rest only show up after it is fixed, which is why adding more groups rarely helps with them.
authentication unavailable: no polkit agent available to authenticate action ‘org.libvirt.unix.manage’
Your user is not in the libvirt group, so polkit wants a password and has no agent to ask through. virt-manager shows the same text in a “Connection Failure” dialog, with QEMU/KVM - Not Connected in the main window. Run sudo usermod -aG libvirt $USER and retry, and there is no need to log out first. If it still fails, check that the rule file exists with ls /usr/share/polkit-1/rules.d/ | grep -i virt, because without it the group grants nothing. Both lab hosts had the file straight after the package install, under a different number on each distro.
Failed to connect socket to ‘/var/run/libvirt/virtnetworkd-sock’: No such file or directory
This one is specific to the modular daemons on Rocky and other EL10 systems. The QEMU socket is up but the network driver’s isn’t, and virtstoraged-sock fails the same way for pools. It isn’t a permission problem, so adding groups won’t help. Enable the driver sockets with the loop from the modular sockets section above.
Requested operation is not valid: network is already active
Harmless. net-start default was run on a network that was already up, which is how Rocky ships it. Nothing changed, so run net-autostart default to be sure it survives a reboot and move on.
virsh list shows no VMs but virt-manager does
virsh is talking to qemu:///session. Confirm with virsh uri, then either add -c qemu:///system or set uri_default as shown earlier. Session-mode VMs run as your user and need direct access to /dev/kvm, which Debian restricts to the kvm group (mode 0660). We did not test session mode, so on Debian stay with the system URI unless you have a reason not to.
Group added but id still doesn’t show libvirt
Expected in the same shell. id -nG reports the groups your session started with, while polkit reads the current group database, so libvirt access works right away even though id lags. Log out and back in when you want the shell to match. If you manage a remote hypervisor rather than a local one, the same group setup applies on that host, and our guide to connect virt-manager to a remote KVM host covers the SSH side.
Hi, i tried to store all my virtual machines on nfs or samba share but i have a lot of problems with permission. I can create volumes but i can’t create virtual machines. The nfs or samba shares are on synology machine.
Unable to complete install: ‘internal error: child reported: unable to set user and group to ‘107:107’ on ‘/mnt/smb/centos7.0.qcow2′: Permission denied’
Hi,
Please Change group ownership for the directory to kvm and retry. It should work fine.
Thanks for the reply, I changed permissions a thousand time, even changed my nfs server operating system once (synology and freenas), nothing worked. Today I found a solution, I do not know if it is safe to do this but it worked: setenforce 0.
Please try this:
Find kvm group ID:
# getent group kvm
kvm:x:36:qemu,sanlock
Then configure your nfs export with below options:
..(rw,anonuid=36,anongid=36,all_squash)
Replace 36 with your KVM group id.
Re-export:
# exportfs -rvv
Let me know if this helps.