On KVM, resizing a volume on RBD primary storage fails in the agent if this host's libvirt has not yet cached the image in its view of the pool. A freshly deployed VM's ROOT volume is the usual case:
resizeVolume id=<ROOT> size=12
-> Failed to resize volume operation of volume UUID: [<uuid>] due to -
org.libvirt.LibvirtException: Storage volume not found: no storage vol with matching path '<ceph pool>/<uuid>'
resizeVolume with a size or a disk offering, changeOfferingForVolume and scaleVirtualMachine all fail the same way, since they all end in the same ResizeVolumeCommand. A size-only grow of a ROOT volume fails too. The resize works again once something else on that host has made libvirt refresh the pool (or after a virsh pool-refresh by hand).
Cause
LibvirtResizeVolumeCommandWrapper gets the disk with pool.getPhysicalDisk() and then looks the volume up through libvirt with conn.storageVolLookupByPath(path) to call StorageVol.resize().
CloudStack creates RBD volumes through librbd (the clone from the template), not through libvirt, so a new volume is not in libvirt's cache on any host until something refreshes the pool there.
The other libvirt volume lookups in the KVM plugin don't depend on getPhysicalDisk(): deletePhysicalDisk() uses getVolume(), which still refreshes on a miss, and LibvirtMigrateCommandWrapper.deleteLocalVolume() only handles local files.
The unit tests mock Connect.storageVolLookupByPath, so they did not see this.
versions
The 4.22 branch since #14188, and main. Released versions without #14188 are not affected. Found while testing #14602 in a lab: KVM, Ceph RBD primary storage, a running Ubuntu VM with its ROOT on RBD.
The steps to reproduce the bug
Deploy a VM on KVM with its ROOT volume on RBD primary storage.
Before anything refreshes the libvirt pool on its host (no virsh pool-refresh, no storage stats poll yet), resize its ROOT volume, for example resizeVolume id=<ROOT> size=<larger>.
The agent fails with "Storage volume not found: no storage vol with matching path ...".
What to do about it?
In the resize wrapper, when the lookup by path fails with "not found" (VIR_ERR_NO_STORAGE_VOL) on an RBD pool, refresh that pool and look the volume up once more. That is what getVolume() did for this path before #14188, and it only costs a refresh when the volume is not cached. Other pool types are unchanged.
threat detection engine error
The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.
What happened
The threat detection engine failed to produce results.
On KVM with RBD primary storage, a resize fails with "Storage volume not found" if libvirt has not yet cached the volume. This happens after #14188, which made getPhysicalDisk() stat RBD images through librbd without refreshing the libvirt pool. The resize wrapper then calls storageVolLookupByPath() against a cold cache. Freshly deployed ROOT volumes are the usual case, and the resize only works after something refreshes the pool. The reporter proposes refreshing the pool once on a "not found" error for RBD pools.
📊 Assessment
Dimension
Value
Reasoning
Type
type:bug
Resize fails until a manual or incidental pool refresh
Component
component:kvm
KVM agent libvirt resize path
Severity
Severity:Major
Resize of new RBD volumes fails; workaround is a manual virsh pool-refresh
Labels
type:bug, component:kvm, Severity:Major
Coding agent
Suitable
Fix is specified: refresh the RBD pool once on not-found, then retry the lookup
Activity
github-actions commented on Nov 9, 2026
Warning
threat detection engine error
What happenedThe threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.
The threat detection engine failed to produce results.
Review the workflow run logs for details.
🎯 Triage report
On KVM with RBD primary storage, a resize fails with "Storage volume not found" if libvirt has not yet cached the volume. This happens after #14188, which made getPhysicalDisk() stat RBD images through librbd without refreshing the libvirt pool. The resize wrapper then calls storageVolLookupByPath() against a cold cache. Freshly deployed ROOT volumes are the usual case, and the resize only works after something refreshes the pool. The reporter proposes refreshing the pool once on a "not found" error for RBD pools.
📊 Assessment
🔗 Similar issues
- KVM: growing a ROOT volume through a new disk offering is refused while the VM is running, though a size-only resize of the same volume works #14601 (related) — KVM ROOT volume grow through disk offering refused while running
- KVM + Linstor: detachVolume reports success but leaves the disk attached when the domain XML still has the legacy /dev/drbdNNNN path #14508 (related) — KVM with Linstor detach reports success while disk remains attached
- VM snapshot merge on KVM can leave volume.path in DB pointing to a file that no longer exists (multi-disk VMs) #14030 (related) — KVM VM snapshot merge leaves volume path pointing to a missing file
💡 Notes and suggestions- Reproduction: deploy a KVM VM with ROOT on RBD, then resize before anything refreshes the libvirt pool on that host.
- Per the reporter, the unit tests mock storageVolLookupByPath, which is why this was not caught; a test that exercises the cold-cache path would help.
Add this agentic workflow to your repoTo install this agentic workflow, run