Introduction
When a non-GPL or out-of-tree kernel module is loaded, the kernel becomes tainted. This is a marker that indicates the kernel is running code that the kernel developers cannot fully support or audit. Taint flags affect how kernel developers handle bug reports and may impact vendor support eligibility. Common sources include NVIDIA proprietary drivers, VMware modules, ZFS (out-of-tree), and certain wireless drivers.
Symptoms
dmesgshowsmodule license 'proprietary' taints kernelcat /proc/sys/kernel/taintedreturns a non-zero value (e.g., 4096, 16384)- Kernel bug reports include
Tainted: G P OEflags - Vendor support may require reproducing the issue on an untainted kernel
- Warning in
journalctl:Disabling lock debugging due to kernel taint
Common Causes
- NVIDIA proprietary GPU driver (taint flag
P- proprietary module) - Out-of-tree modules loaded via DKMS (taint flag
O- out-of-tree) - Force-loaded modules that do not match the running kernel version (taint flag
F) - Unsigned modules on a Secure Boot system (taint flag
E- unsigned) - Modules with workaround flags enabled (taint flag
W- warning previously issued)
Step-by-Step Fix
- 1.Check current taint status:
- 2.```bash
- 3.cat /proc/sys/kernel/tainted
- 4.# Decode the value
- 5.# 1 = TAINT_PROPRIETARY_MODULE (P)
- 6.# 2 = TAINT_FORCED_MODULE (F)
- 7.# 4 = TAINT_UNSAFE_SMP (S)
- 8.# 8 = TAINT_FORCED_RMMOD (R)
- 9.# 16 = TAINT_MACHINE_CHECK (M)
- 10.# 32 = TAINT_BAD_PAGE (B)
- 11.# 4096 = TAINT_USER (U)
- 12.# 8192 = TAINT_DIE (D)
- 13.# 16384 = TAINT_OVERRIDDEN_ACPI_TABLE (A)
- 14.# 32768 = TAINT_WARN (W)
- 15.# 65536 = TAINT_CRAP (C)
- 16.# 131072 = TAINT_FIRMWARE_WORKAROUND (I)
- 17.# 262144 = TAINT_OOT_MODULE (O)
- 18.# 524288 = TAINT_UNSIGNED_MODULE (E)
- 19.
` - 20.Identify which modules caused the taint:
- 21.```bash
- 22.dmesg | grep -i taint
- 23.# Shows: "nvidia: module license 'NVIDIA' taints kernel."
# List all loaded modules and their license for mod in $(lsmod | awk 'NR>1 {print $1}'); do license=$(modinfo $mod 2>/dev/null | grep license) echo "$mod: $license" done | grep -v "GPL" ```
- 1.Remove proprietary modules if untainted kernel is needed:
- 2.```bash
- 3.sudo rmmod nvidia_uvm nvidia_drm nvidia_modeset nvidia
- 4.# Verify taint is cleared (only if all tainted modules removed)
- 5.cat /proc/sys/kernel/tainted
- 6.
` - 7.Replace proprietary drivers with open-source alternatives where possible:
- 8.```bash
- 9.# Instead of NVIDIA proprietary driver, use nouveau:
- 10.sudo apt install xserver-xorg-video-nouveau
- 11.sudo rm /etc/modprobe.d/blacklist-nouveau.conf
- 12.sudo update-initramfs -u
- 13.sudo reboot
- 14.
` - 15.Document taint status for support cases:
- 16.```bash
- 17.# Capture full taint information for vendor support
- 18.echo "=== Kernel Taint Status ===" > /tmp/taint-report.txt
- 19.cat /proc/sys/kernel/tainted >> /tmp/taint-report.txt
- 20.echo "=== Tainted Modules ===" >> /tmp/taint-report.txt
- 21.dmesg | grep -i taint >> /tmp/taint-report.txt
- 22.
` - 23.Use the taint decode kernel script:
- 24.```bash
- 25.# Modern kernels include a decoder
- 26.sudo cat /proc/sys/kernel/tainted | python3 -c "
- 27.import sys
- 28.flags = int(sys.stdin.read().strip())
- 29.flag_map = {
- 30.0: 'P', 1: 'F', 2: 'S', 3: 'R', 4: 'M',
- 31.5: 'B', 12: 'U', 13: 'D', 14: 'A',
- 32.15: 'W', 16: 'C', 17: 'I', 18: 'O', 19: 'E'
- 33.}
- 34.result = ''
- 35.for bit, char in flag_map.items():
- 36.if flags & (1 << bit):
- 37.result += char
- 38.print(f'Taint flags: {result}')
- 39."
- 40.
`
Prevention
- Prefer open-source drivers (nouveau, radeon, amdgpu) over proprietary ones
- Document all taint flags and their sources in your infrastructure inventory
- For support cases with Red Hat, SUSE, or Canonical, disclose taint status upfront
- Test kernel upgrades on systems with proprietary modules before production deployment
- Consider the trade-off between performance (proprietary) and supportability (open-source)