Resolving Kernel Compatibility Issues During VM Migration
When a migrated VM ends up with a kernel it shouldn’t have, the instinct is to assume something’s wrong with the new server itself, a bad image, an old template, something on the CloudStack side. In our case the actual cause sits somewhere less obvious: the file transfer step of the migration tool itself. Once you understand how the tool provisions the destination VM, the whole problem makes a lot more sense, and so does the fix.
How the New VM Actually Gets Its Kernel
Our migration tool provisions the destination VM fresh, spinning up a new CloudStack instance on the latest available OS image. That new instance already comes with a current, stable kernel installed as part of the base image itself, nothing wrong with it at that point. The next step is moving the application over from the old Virtuozzo container to that new VM, and that’s done with rsync.
The problem is that an rsync transfer scoped too broadly doesn’t know to leave kernel related paths alone. If the sync includes directories like /boot or /lib/modules, it will happily copy whatever kernel files existed on the old Virtuozzo container straight over the new VM’s own, already correct, kernel files. The destination VM started out with a perfectly good modern kernel and ends up with an old, outdated one overwritten on top of it by the migration itself.
Why This Is Easy to Miss at First
This one doesn’t announce itself the way a driver failure would. The VM still boots. The application still starts. Whatever breaks tends to show up as something vague, odd module errors, a service that behaves inconsistently, something that doesn’t cleanly map back to “the kernel is wrong” unless you specifically go check it. It looks like a hundred other post-migration issues before you actually compare what kernel is running against what should have been installed by the base image in the first place.
How can we fix the Kernel Compatibility issue during Migration
Step 1: Confirm the Kernel Doesn’t Match What the Base Image Should Have Shipped
Check what’s actually running against what the OS image is supposed to provide:
uname -r
Compare that version against the current stable kernel for whatever OS image the migration tool provisions by default. If the running kernel is noticeably older than what a fresh install of that image would normally have, that’s the signal something got overwritten during the file transfer rather than the new instance simply having its own default kernel.
It’s also worth checking the installed kernel packages directly, since the package database can show a version that doesn’t match what actually got dropped into /boot:
rpm -qa kernel*Â Â Â Â # RHEL / AlmaLinux
dpkg -l | grep linux-image  # Ubuntu / Debian
A mismatch between what the package manager thinks is installed and what’s actually sitting in /boot is a strong sign the rsync step wrote over files it shouldn’t have touched.
Step 2: Fix the rsync Command So It Never Touches Kernel Files Again
The real fix is upstream of the symptom: scope the rsync transfer so it can’t touch kernel related paths in the first place. Excluding these directories keeps the destination’s own kernel exactly as the base image installed it:
rsync -avz –exclude ‘/boot/*’ –exclude ‘/lib/modules/*’ –exclude ‘/usr/lib/modules/*’ /source/path/ /destination/path/
This is the same principle as excluding cache and temp directories to avoid transferring things that shouldn’t move, just applied to something with a lot more consequence if it gets copied over by mistake. The application data, configs, and everything else that actually needs to move across still transfers normally, kernel and module files just aren’t part of that transfer anymore.
Step 3: Repair a VM That Already Got the Old Kernel Copied Onto It
If a VM has already been affected, reinstalling the correct kernel package restores it without needing to reprovision the whole instance:
dnf reinstall kernel -y               # RHEL / AlmaLinux
apt install –reinstall linux-image-$(uname -r) -y  # Ubuntu / Debian
Follow that with a GRUB config regeneration and a reboot to make sure the correct kernel is actually the one being loaded, not just the one sitting in /boot alongside stale files from the old container.
Conclusion
This isn’t a hardware or driver compatibility problem, it’s a side effect of how the migration tool moves data: a fresh VM with a perfectly good kernel gets an old one copied on top of it because the rsync transfer wasn’t scoped to leave /boot and module directories alone. Checking the running kernel against what the base image should have shipped catches it, and excluding kernel related paths from the rsync command in the first place is what actually stops it from happening again.