Blog

Why the VNC keyboard doesn't work on Debian Cloud images

03 Mar 2026 · 2 min read
Why the VNC keyboard doesn't work on Debian Cloud images

You open the VNC console of a Debian VM on OpenStack. Login prompt shows up. You start typing. Nothing. Cursor doesn't move. Mouse works, screen renders, but the keyboard is dead.

It's not a noVNC bug, not a browser issue, not a QEMU misconfiguration. It's the kernel.

The problem

Official Debian GenericCloud images (Debian 12, 13, and likely future releases) ship with a cloud kernel variant. This kernel strips out drivers to keep the image small and boot fast.

One of the things it strips: all USB support.

$ grep USB_SUPPORT /boot/config-$(uname -r)
# CONFIG_USB_SUPPORT is not set

Why does that matter? Because QEMU (the hypervisor behind OpenStack) exposes a virtual USB keyboard to the guest. When you type in the VNC console, QEMU receives the events and forwards them through this USB device.

No USB driver in the kernel means the device simply doesn't exist inside the guest:

$ cat /proc/bus/input/devices | grep Name
N: Name="AT Translated Set 2 keyboard"    # PS/2 only, no USB
N: Name="Power Button"

Compare with a working AlmaLinux or CentOS VM:

$ cat /proc/bus/input/devices | grep Name
N: Name="AT Translated Set 2 keyboard"
N: Name="VirtualPS/2 VMware VMMouse"
N: Name="QEMU QEMU USB Tablet"
N: Name="QEMU QEMU USB Keyboard"          # this receives VNC input
N: Name="Power Button"

QEMU QEMU USB Keyboard — that's the device missing on Debian.

The fix

Install the standard Debian kernel (non-cloud), which includes USB support:

export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y linux-image-amd64

Set the standard kernel as the default in GRUB:

# Switch to saved default
sed -i 's/GRUB_DEFAULT=.*/GRUB_DEFAULT=saved/' /etc/default/grub

# Find the standard kernel entry
GRUB_ENTRY=$(grep -oP "gnulinux-advanced-[a-f0-9-]+" /boot/grub/grub.cfg | head -1)
STD_ENTRY=$(grep -oP "gnulinux-[0-9][^']*-advanced-[a-f0-9-]+" /boot/grub/grub.cfg | grep -v cloud | head -1)
grub-set-default "${GRUB_ENTRY}>${STD_ENTRY}"
update-grub

Optionally, remove the cloud kernel to save space:

apt-get remove -y linux-image-*-cloud-*
apt-get autoremove -y

Reboot. After restart, verify:

$ uname -r
6.12.73+deb13-amd64     # standard, not cloud

$ cat /proc/bus/input/devices | grep Name
N: Name="AT Translated Set 2 keyboard"
N: Name="QEMU QEMU USB Tablet"
N: Name="QEMU QEMU USB Keyboard"    # now it exists

VNC keyboard works.

For image builders

If you build cloud images with Packer or similar tooling, add the kernel swap step to your Debian provisioning. This script auto-detects whether it's running a cloud kernel:

#!/bin/bash
export DEBIAN_FRONTEND=noninteractive

if [[ "$(uname -r)" != *"cloud"* ]]; then
    echo "Not a cloud kernel, skipping"
    exit 0
fi

apt-get update -qq
apt-get install -y linux-image-amd64

sed -i 's/GRUB_DEFAULT=.*/GRUB_DEFAULT=saved/' /etc/default/grub
GRUB_ENTRY=$(grep -oP "gnulinux-advanced-[a-f0-9-]+" /boot/grub/grub.cfg | head -1)
STD_ENTRY=$(grep -oP "gnulinux-[0-9][^']*-advanced-[a-f0-9-]+" /boot/grub/grub.cfg | grep -v cloud | head -1)
grub-set-default "${GRUB_ENTRY}>${STD_ENTRY}"
update-grub

apt-get remove -y linux-image-*-cloud-*
apt-get autoremove -y
apt-get clean
rm -rf /var/lib/apt/lists/*

The resulting image will boot with the standard kernel and VNC will work out of the box.

Why CentOS/AlmaLinux/Rocky/Fedora aren't affected

Cloud kernels on RHEL-based distros don't disable USB. They ship with CONFIG_USB_SUPPORT=y and all the necessary HID modules. VNC works out of the box on these distros.

Ubuntu cloud images — worth testing. They may or may not have the same issue.

TL;DR

Debian cloud kernel = no USB = no VNC keyboard. Install linux-image-amd64, set it as default, reboot. Done.

linux debian openstack troubleshooting