If you have ever been typing away and noticed random characters appearing that you never pressed, you are not alone. Ghost characters from USB wireless keyboards are a surprisingly common nuisance on Linux systems, and the fix is simpler than you might expect. This article walks through what causes the problem and how to resolve it permanently with a one-line kernel module configuration.
Ghost characters are keystrokes that appear in your text editor, terminal, or browser without you having pressed anything. They can show up as random letters, numbers, or symbols, and they tend to appear in bursts. If you are using a wireless keyboard with a USB dongle receiver, the culprit is almost certainly the USB polling rate.
The polling rate determines how frequently the operating system queries your USB device for new input. A higher polling rate means more frequent checks. On paper this sounds like a good thing, but in practice it can cause the HID (Human Interface Device) driver to misread the input buffer on certain wireless keyboards, interpreting noise or incomplete packets as legitimate keystrokes. The result is ghost characters appearing seemingly at random.
This is a known quirk with the usbhid kernel module on Linux, and it affects a wide range of wireless keyboards across different brands. It is not a hardware fault with your keyboard, and you do not need to replace anything.
The usbhid module is the Linux kernel driver responsible for all USB human interface devices, which includes keyboards, mice, and game controllers. It exposes a parameter called mousepoll that controls the polling interval in milliseconds for USB input devices.
By default, the polling interval is set to 0, which tells the kernel to use the value reported by the device itself. On many wireless USB keyboards and their receivers, the device-reported interval is very short, effectively resulting in a high polling rate. This aggressive polling is what triggers the ghost character behaviour.
Setting mousepoll=2 changes the polling interval to 2 milliseconds, which corresponds to a 500 Hz polling rate. This is still more than adequate for responsive keyboard and mouse input, but it is conservative enough to prevent the driver from over-querying wireless receivers that cannot keep up at higher rates.
The solution involves two steps: writing a persistent configuration file so the setting survives reboots, and then reloading the module so the change takes effect immediately without requiring a restart.
Open a terminal and create (or edit) the usbhid configuration file:
sudo nano /etc/modprobe.d/usbhid.conf
Add the following line:
options usbhid mousepoll=2
Save and close the file. On most distributions this directory is read at boot time by initramfs or systemd, so the option will be applied automatically on every subsequent start.
To apply the change right now without rebooting, unload the usbhid module:
sudo modprobe -r usbhid
Then physically remove the USB dongle from your machine and plug it back in. Linux will reload the usbhid module automatically when it detects the device, and this time it will pick up the new mousepoll setting from your configuration file.
Your keyboard should now behave normally. The ghost characters will stop.
You might wonder why you cannot simply run sudo modprobe usbhid to reload the module after unloading it. The reason is that the module needs an active device to initialise against. If you load it without any USB HID devices connected, it loads in a dormant state and may not correctly apply the module options until a device is actually attached.
Removing and reinserting the dongle forces a full device enumeration cycle. The kernel detects the new device, loads usbhid with all parameters from /etc/modprobe.d/, and correctly initialises the driver with mousepoll=2 from the start. It is a small but important distinction.
If removing the dongle is inconvenient (for example, if it is at the back of a desktop machine), you can alternatively run:
sudo modprobe -r usbhid && sudo modprobe usbhid
followed by a re-plug, or simply reboot. The configuration file ensures the fix is permanent regardless of method.
This is the most common concern people raise. The short answer is: not noticeably.
A polling rate of 500 Hz (one poll every 2 milliseconds) is well above what most users can perceive in day-to-day computing. Even competitive gaming mice typically operate at 125 Hz to 1000 Hz, and 500 Hz sits comfortably in the middle of that range. For office use, browsing, and general typing, you will not notice any difference in responsiveness.
If you are using a high-performance wired gaming mouse and you are concerned about the impact, you can scope the configuration more narrowly. The usbhid module does support per-device options using vendor and product IDs, though for most users the global mousepoll=2 setting is the simplest and most reliable approach.
If you want to confirm what polling rate your devices are currently using before and after the fix, you can inspect the kernel's USB device information. Run the following to list all HID devices and their reported intervals:
grep -r bInterval /sys/bus/usb/devices/*/bInterval 2>/dev/null
Each device reports its interval in frames (milliseconds for full-speed USB). A value of 1 means 1 ms intervals (1000 Hz), while 8 means 8 ms (125 Hz). After applying the mousepoll=2 fix and reinserting your dongle, you should see the effective polling rate reflected in how the kernel interacts with the device, though note that bInterval reflects what the device requests, not necessarily what the driver enforces.
For a more direct confirmation, check dmesg immediately after reinserting the dongle:
sudo dmesg | tail -20
Look for lines mentioning usbhid and your device. If the module loaded cleanly with your options applied, you will see the device initialised without errors.
On some distributions, particularly Debian and Ubuntu-based systems, changes to /etc/modprobe.d/ do not automatically propagate into the initramfs image that is loaded at boot. If you find that the ghost characters return after a reboot despite having the configuration file in place, regenerate your initramfs with:
sudo update-initramfs -u
On Fedora and RHEL-based systems, the equivalent command is:
sudo dracut --force
On Arch Linux, run:
sudo mkinitcpio -P
After regenerating, reboot and the mousepoll=2 option will be baked into the boot image and applied before any USB devices are initialised.
Ghost characters from a USB wireless keyboard on Linux are caused by the usbhid kernel module polling the device at a rate the wireless receiver cannot cleanly handle. The fix is to set mousepoll=2 in /etc/modprobe.d/usbhid.conf, reload the module, and replug the USB dongle. The change is persistent across reboots and has no meaningful impact on input responsiveness for everyday use.
If the problem persists after following these steps, it is worth checking whether your keyboard firmware has an update available, and also whether the issue occurs on a different USB port. Some USB controllers handle wireless receivers better than others, and moving the dongle from a USB 3.0 port to a USB 2.0 port occasionally resolves lingering issues of this type.