Note
This functionality requires virt-v2v (https://www.libguestfs.org/virt-v2v.1.html) binary installed on destination cluster hosts (needs to be installed manually as it's not a dependency of the CloudStack agent during the agent installation).
The CloudStack agent does not install the virt-v2v binary as a dependency. The virt-v2v binary must be installed manually on KVM hosts, or the migration will fail.
Note
Newer versions of virt-v2v - v2.7.x on EL9 variants, v2.4.x on Ubuntu 24.04 - are strongly advised. Older versions of virt-v2v - e.g. v1.4.x should be avoided.
The virt-v2v output (progress) is logged in the CloudStack agent logs, to help administrators track the progress on the Instance conversion processes. The verbose mode for virt-v2v can be enabled by adding the following line to /etc/cloudstack/agent/agent.properties and restart cloudstack-agent:
dnf install virt-v2v / apt install virt-v2v echo "virtv2v.verbose.enabled=true" >> /etc/cloudstack/agent/agent.properties systemctl restart cloudstack-agent
Installing virt-v2v on Ubuntu KVM hosts does not install nbdkit, which is required in the conversion of VMware VCenter guests. To install it, please execute:
apt install nbdkit
Supported Distributions for KVM Hypervisor:
.. cssclass:: table-striped table-bordered table-hover
| Linux Distribution | Supported Versions |
|---|---|
| Alma Linux | 8, 9 |
| Red Hat Enterprise Linux | 8, 9 |
| Rocky Linux | 8, 9 |
| Ubuntu | 22.04 LTS, 24.04 LTS |
Recommended distributions, due to the most recent virt-v2v version (EL9 prefered)
.. cssclass:: table-striped table-bordered table-hover
| Linux Distribution | Versions |
|---|---|
| Alma Linux | 9 |
| Red Hat Enterprise Linux | 9 |
| Rocky Linux | 9 |
| Oracle Linux | 9 |
| Ubuntu | 24.04 LTS |
Importing Windows VMs from VMware requires installing the virtio drivers inside that Windows VMs and that is executed by the host running virt-v2v conversion.
The Fedora-provided virtio-win RPM installs the drivers under /usr/share/virtio-win, which is one of virt-v2v's
default search paths.
On EL-based hosts, including RHEL, Oracle Linux, Rocky Linux and Alma Linux, install the Fedora-provided RPM directly.
dnf install -y https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.noarch.rpm rpm -qa | grep -i virtio-win ls -l /usr/share/virtio-win
For Debian-based distributions (alien is needed for conversion of .rpm to .deb package):
wget -O virtio-win.noarch.rpm https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.noarch.rpm apt -y install alien alien -d virtio-win.noarch.rpm dpkg -i virtio-win*.deb ls -l /usr/share/virtio-win
Note
Never rely on the virtio-win package from the Enterprise Linux distribution
repositories: it lags the upstream project considerably and may contain no drivers at
all for recent Windows releases (for example, the EL9 package 1.9.40 has no drivers
for Windows Server 2025). virt-v2v then converts the guest without a virtio storage
driver and the imported VM cannot boot from its virtio disk. If the guest's Windows
release is newer than the drivers in the installed RPM, overwrite the ISO with the
latest upstream build:
curl -L -o /usr/share/virtio-win/virtio-win.iso https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso
Note
Windows Server 2025 enforces a stricter driver-signature policy at runtime and, as of
virtio-win 0.1.285, rejects the optional smbus driver's certificate during the
first-boot driver installation. virt-v2v retries the failed installation on every
boot, which leaves the imported guest in a reboot loop. The driver is a non-essential
SMBus stub; the essential storage and network drivers install fine.
This affects Windows Server 2025 and newer only - older Windows releases
(Windows Server 2016/2019/2022, Windows 10/11) accept the driver's signature and work
fine with the unmodified upstream ISO, so no action is needed for them. Until this is
resolved in the virtio-win project, rebuild the ISO on the conversion host without the
smbus files before converting Windows Server 2025 guests (virt-v2v reads the
drivers from /usr/share/virtio-win/virtio-win.iso, so the ISO itself has to be
modified):
dnf install -y xorriso xorriso -osirrox on -indev /usr/share/virtio-win/virtio-win.iso -extract / /tmp/virtio-win-extracted chmod -R u+w /tmp/virtio-win-extracted find /tmp/virtio-win-extracted -iname 'smbus.*' -delete xorriso -as mkisofs -o /usr/share/virtio-win/virtio-win.iso -J -R -V virtio-win /tmp/virtio-win-extracted rm -rf /tmp/virtio-win-extracted
On some distros, the Windows helper binary "rhsrvany.exe", which is used for Windows-based VM firstboot scripts and some other actions, might be missing.
To avoid virt-v2v error like virt-v2v: error: One of rhsrvany.exe or pvvxsvc.exe is missing in /usr/share/virt-tools - check if the file exists (it's actually a symbolic link):
ls -la /usr/share/virt-tools/rhsrvany.exe
If the file does not exist, proceed with the commands below (EL8 and EL9 variants usually already have this in place, so are not affected)
Ubuntu-based distros
wget -nd -O srvany.rpm https://kojipkgs.fedoraproject.org/packages/mingw-srvany/1.1/4.fc38/noarch/mingw32-srvany-1.1-4.fc38.noarch.rpm [ -f /usr/bin/alien ] || apt -y install alien alien -d srvany.rpm dpkg -i *srvany*.deb mkdir -p /usr/share/virt-tools ln -sf /usr/i686-w64-mingw32/sys-root/mingw/bin/rhsrvany.exe /usr/share/virt-tools/rhsrvany.exe ln -sf /usr/i686-w64-mingw32/sys-root/mingw/bin/pnp_wait.exe /usr/share/virt-tools/pnp_wait.exe ls -la /usr/share/virt-tools/rhsrvany.exe
The OVF tool (ovftool) must be installed on the destination KVM hosts if the hosts are to export VM files (OVF) from vCenter. If not, the management server exports them (the management server doesn't require ovftool installed).
Download the ovftool from https://developer.broadcom.com/tools/open-virtualization-format-ovf-tool/latest
unzip VMware-ovftool-4.6.3-24031167-lin.x86_64.zip -d /usr/local/ #create a soft link ln -s /usr/local/ovftool/ovftool /usr/local/bin/ovftool
If you are hitting the following error when running ovftool, install the dependency
./ovftool.bin: error while loading shared libraries: libnsl.so.1: cannot open shared object file: No such file or directory
dnf install libnsl
CloudStack supports an optimized VMware-to-KVM migration path using virt-v2v in vpx input mode combined with VMware's Virtual Disk Development Kit (VDDK). This method eliminates the OVF export phase entirely and streams disk blocks directly from the source hypervisor into the conversion pipeline, resulting in significantly faster migration times.
The traditional OVF-based workflow operates in two sequential phases:
- Export the entire VM as OVF/VMDK files to temporary storage (full disk copy).
- Convert the local VMDK files using virt-v2v (second full disk read and write).
The VDDK-based workflow replaces both phases with a single streaming pipeline:
- virt-v2v connects directly to vCenter via
vpx:// - Disk blocks are read on demand via VDDK (using nbdkit internally as the translation layer between the VDDK API and virt-v2v's NBD block device interface)
- Conversion and disk transfer happen concurrently
- Only allocated blocks are transferred; zero-filled and sparse extents are skipped
- No intermediate OVF or VMDK files are created
This reduces disk I/O amplification, eliminates temporary staging storage, and shortens end-to-end migration time.
Note
CloudStack does not distribute VDDK, operators must download it separately. Along with the new VDDK-based conversion method, the traditional OVF-based method remains supported for environments. Operators can choose the conversion method on a per-migration basis in the UI import wizard.
To use VDDK-based migration, operators must prepare each KVM host that will run the conversion: install the conversion tools, install VDDK manually, configure libguestfs, and verify host connectivity to vCenter/ESXi.
Example: prepare one KVM conversion host
Step 1: Install the conversion stack
Install the required conversion tools on the KVM host. Choose the appropriate command for your distribution:
RHEL / Rocky / Alma Linux:
dnf install -y epel-release dnf config-manager --set-enabled crb dnf install -y virt-v2v libguestfs-tools libguestfs-xfs qemu-img nbdkit
Ubuntu:
apt install -y \ virt-v2v \ libguestfs-tools \ libguestfs-xfs \ qemu-utils \ qemu-system-x86 \ libvirt-clients \ nbdkit
Step 2: Download and install VDDK
Download the VDDK Linux tarball from Broadcom's VMware Virtual Disk Development Kit page: https://developer.broadcom.com/sdks/vmware-virtual-disk-development-kit-vddk/
Use the latest available VDDK 8.x Linux tarball for all supported KVM conversion hosts, including EL8, EL9,
Ubuntu 22.04, and Ubuntu 24.04 hosts. VDDK 8.x covers vSphere 7 and vSphere 8 environments and is the recommended
stable choice for most deployments. Do not use VDDK 9.x unless the source environment is vSphere 9 and the
virt-v2v and nbdkit package combination has been explicitly validated, because VDDK 9.x is targeted at
vSphere 9 and is not the expected default for vSphere 7 or vSphere 8 environments.
Extract the tarball under a consistent location such as the example below, and always configure that directory
explicitly with the vddk.lib.dir property in /etc/cloudstack/agent/agent.properties (see the configuration
reference further down). The agent does attempt to auto-detect a vmware-vix-disklib-distrib directory when the
property is not set, but relying on auto-detection is strongly discouraged: on a real host the search can pick up the
wrong VDDK libraries - leftovers from container images, a second VDDK installation, or a partially extracted tree -
and the resulting conversion failures are hard to trace back to the wrong library path. Treat auto-detection as a
fallback only; set vddk.lib.dir on every conversion host.
mkdir -p /opt/vmware-vddk # VDDK 8.x example for EL8, EL9, Ubuntu 22.04, and Ubuntu 24.04 hosts tar -xf VMware-vix-disklib-8*.tar.gz -C /opt/vmware-vddk
Expected layout after extraction:
/opt/vmware-vddk/vmware-vix-disklib-distrib/ lib64/ include/ bin64/
Step 3: Verify host setup
nbdkit vddk --dump-plugin libdir=/opt/vmware-vddk/vmware-vix-disklib-distrib/lib64 | grep vddk_library_version virt-v2v --version nbdkit --version
Step 4: Restart the CloudStack agent
Restart the CloudStack agent service so it detects the installed VDDK library and makes it available in the UI:
systemctl restart cloudstack-agent
After the agent restarts, verify that VDDK installation was detected by checking the host details in the CloudStack UI.
Step 5: Verify required network and firewall access
Allow the following ports through any firewall or network security controls between the KVM conversion host and the VMware endpoints:
.. cssclass:: table-striped table-bordered table-hover
| Target | Port | Purpose |
|---|---|---|
| vCenter | 443 | API / authentication |
| ESXi hosts | 902 | VDDK NFC disk transfer |
| ESXi hosts | 443 | VM metadata |
The following properties can be configured in /etc/cloudstack/agent/agent.properties on each KVM host to enable and tune the VDDK-based conversion.
After editing this file, restart the CloudStack agent (systemctl restart cloudstack-agent).
These values can also be passed in details parameters in importVm API as key-value pairs.
.. cssclass:: table-striped table-bordered table-hover
| Property | Description | Default / Example |
|---|---|---|
vddk.lib.dir |
Path to the VDDK library directory on the KVM host.
Passed to virt-v2v as -io vddk-libdir=<path>. |
/opt/vmware-vddk/vmware-vix-disklib-distrib |
vddk.transports |
Ordered VDDK transport preference.
Passed as -io vddk-transports=<value> to virt-v2v. |
Example: nbd:nbdssl |
vddk.thumbprint |
Optional vCenter SHA1 thumbprint.
Passed as -io vddk-thumbprint=<value> to virt-v2v. |
If unset, CloudStack computes it automatically on
the KVM host via openssl. |
Example configuration in /etc/cloudstack/agent/agent.properties:
# LIBGUESTFS backend to use for VMware to KVM conversion via VDDK (default: direct) libguestfs.backend=direct # Path to the VDDK library directory for VMware to KVM conversion via VDDK, # passed to virt-v2v as -io vddk-libdir=<path> vddk.lib.dir=/opt/vmware-vddk/vmware-vix-disklib-distrib # Ordered VDDK transport preference for VMware to KVM conversion via VDDK, passed as # -io vddk-transports=<value> to virt-v2v. Example: nbd:nbdssl # vddk.transports=nbd:nbdssl # Optional vCenter SHA1 thumbprint for VMware to KVM conversion via VDDK, passed as # -io vddk-thumbprint=<value>. If unset, CloudStack computes it on the KVM host via openssl. # vddk.thumbprint=
VM state before conversion
- Windows VMs: Must be powered off and gracefully shut down before conversion to ensure the filesystem is in a clean state.
Use a single primary storage pool for direct conversion
When VDDK-based conversion is enabled, it is strongly recommended to configure the conversion to write directly
to the destination primary storage pool (i.e., set Convert to storage pool directly to true in the import wizard).
This eliminates the two-step process of the traditional OVF method, conversion to temporary storage followed by
an import step, replacing it with a single streaming pipeline that writes converted QCOW2 disks directly to the
destination primary storage.
Network placement for optimal disk transfer throughput
For best performance, place the KVM conversion host on the same high-bandwidth network as the source ESXi hosts. VDDK disk transfer uses VMware's NFC protocol on TCP port 902. ESXi routes NFC traffic to the conversion host based on standard IP routing, if the conversion host is reachable over a dedicated storage or migration network, ESXi will naturally select that VMkernel interface for disk transfer, keeping bulk data off the management network without requiring any special configuration in virt-v2v or CloudStack.
In the UI, Virtual Machines to import from VMware are listed in Tools > Import-Export Instances section, selecting:
.. cssclass:: table-striped table-bordered table-hover
| Select Import-Export Source Hypervisor | Action |
|---|---|
| VMware | Migrate existing instances to KVM |
CloudStack administrators must select a KVM cluster to import the VMware Virtual Machines (right side of the image above). Once a KVM cluster is selected, the VMware Datacenter selection part is displayed.
CloudStack administrators must select the Source VMware Datacenter:
- Existing: The existing zones are listed, and for each zone, CloudStack will list if there is any VMware Datacenter associated with it. In case it is, it can be selected.
- External: CloudStack allows listing Virtual Machines from a VMware Datacenter that is not associated with any CloudStack zone. To do so, the vCenter IP address, the datacenter name, and username and password credentials are needed to log in to the vCenter. To import from a standalone VMware host, you can use the default datacenter name (ha-datacenter or other) along with the host credentials (Only stopped VMs are supported).
Once the VMware Datacenter is selected, click on List VMware Instances to display the list of Virtual Machines in the Datacenter. You must then choose the VMware Instance for import and click on Import Instance.
Note
CloudStack allows importing Running Linux Virtual Machines, but it is generally recommended that the Virtual Machine to import is powered off and has been gracefully shut down before the process starts. In case a Linux VM is imported while running, it will be converted in a "crash consistent" state. For Windows Virtual Machines, it is not possible to import them while running, they must be shut down gracefully so the filesystem is in a clean state.
Note
You can configure the parallel import of VM disk files on KVM host and management server, using the global settings: threads.on.kvm.host.to.import.vmware.vm.files and threads.on.ms.to.import.vmware.vm.files respectively.
In the UI import wizard, administrators can select:
- (Optional) A KVM host to perform the conversion (must have virt-v2v installed). In case it is not set, then a KVM host is randomly selected.
- (Optional) A KVM host to import the converted files into CloudStack (this host must have access to the temporary conversion storage in order to move the converted files to the destination storage). In case it is not set, then a KVM host is randomly selected.
- (Optional) Extra parameters: in case the global setting convert.vmware.instance.to.kvm.extra.params.allowed (disabled by default) is enabled, then administrators are allowed to pass extra parameters for the virt-v2v conversion command. This setting must be set along with the setting convert.vmware.instance.to.kvm.extra.params.allowed.list (empty by default) which indicates the list of parameters that CloudStack will accept for passing to the virt-v2v conversion command on the KVM hosts.
Since version 4.22 it is possible to indicate converting to storage pool directly (not using temporary storage for conversion). This is set to false by default, in which case a temporary conversion storage is used.
- When set to false (temporary storage used), then administrators must select a Temporary destination storage. The default is Secondary Storage, but if using Primary Storage - only NFS pools are supported.
- When set to true (not using temporary storage), then administrators must select the destination storage pool. The supported storage pools are: NFS, Local Storage and SharedMountPoint storage pools, under the following assumptions:
- The KVM host for conversion must be selected and must have access to the destination storage
- The KVM host for importing must be selected and must have access to the destination storage
- In case of Local storage, the selected KVM host for conversion must be the same as the KVM host for importing
Since version 4.22.1 it is possible to select the Guest OS for the VM to be imported, based on the source VMware VM Guest OS.
- When CloudStack has Guest OS mappings for the source VMware Guest OS VM, then the list of supported Guest OS is displayed and administratos can select one of them.
- In case there are no Guest OS mappings for the source VMware Guest OS VM, then the default import template Guest OS will be used.
The conversion is performed on a random (or explicitly chosen) KVM host (if the ovftools are installed), otherwise, the management server will export/copy the VM files (optionally, you can force this action to be done by the management server even the KVM hosts have the ovftools installed in it). Irrelevant if the KVM host or the management server performs the copy of the VM files (OVF), you can further either let CloudStack choose which KVM host should do the conversion of the VM files using virt-v2v and which host will import the files to the destination Primary Storage Pool, or you can explicitly choose these KVM hosts for each of the 2 mentioned operations.
When importing an instance from VMware to KVM (OVF method), CloudStack performs the following actions:
- Export the VM files (OVF) of the instance to a temporary storage location (which can be selected by the administrator). The export is performed by a KVM host if ovftool is installed or management server (can be forced by the administrator, doesn't need ovftool installed on the management server). The existence of ovftool on KVM host is checked using
ovftool --versioncommand.
- If the instance on VMware is in running state, we clone the instance on VMware and use the new cloned instance to export OVF files. The cloning process may take some time to complete and is used to ensure data consistency, disk consolidation, etc.
- If the instance on VMware is in stopped state, we directly use the instance to export its OVF files.
- Converts the OVF on the temporary storage location to KVM using virt-v2v. CloudStack (or the administrator) selects a running and enabled KVM host to perform the conversion (of the previously exported OVF files) from VMware to KVM using virt-v2v. If the binary is not installed, then the host will fail to convert the Instance. In case it is installed, it will perform the conversion into the temporary location to store the converted QCOW2 disks of the instance. The virt-v2v conversion is a long-lasting process which can be set to time out by the global setting
convert.vmware.instance.to.kvm.timeout. The conversion process takes a long time because virt-v2v creates a temporary instance to inspect the source VM and generate the converted disks with the correct drivers. Additionally, it needs to copy the converted disks into the temporary location.- The converted instance (i.e. QCOW2 files) is then imported into the chosen KVM cluster. Administrator can choose the KVM host to perform the import or let CloudStack choose it. Only enabled cluster and enabled hosts are considered.
Note
Please do not restart the management servers while migration is in progress as it will lead to the interruption of the process and you will need to start again.
Note
As mentioned above, the migration/conversion process uses an external tool, virt-v2v, which supports most but not all the operating systems out there (this is true for both the host on which the virt-v2v tool is running as well as the guest OS of the instances being migrated by the tool). Thus, the success of the import process will, almost exclusively, depend on the success of the virt-v2v conversion. In other words, the success will vary based on factors such as the current OS version, installed packages, guest OS setup, file systems, and others. Success is not guaranteed. We strongly recommend testing the migration process before proceeding with production deployments.
Note
The resulting imported VM uses the default Guest OS type: CentOS 4.5 (32-bit). After importing the VM, please Edit the Instance to change the Guest OS Type accordingly.
Since version 4.22 administrators can monitor the VMware to KVM migration jobs. The new section is displayed on Tools > Import-Export Instances > Migrate existing instances to KVM > VM Import Tasks:
The tasks can be filtered by state: Completed, Running or Failed, or listing all the tasks.


