DKMS, VirtualBox, NVIDIA drivers, Broadcom wireless modules, and other kernel-module workflows all fail the same way when Ubuntu cannot find headers for the kernel you are actually running. To install Linux kernel headers on Ubuntu, match the header package to uname -r first, then keep the right GA or HWE metapackage installed so future kernel updates bring matching headers with them.
The commands apply to Ubuntu 26.04 LTS, 24.04 LTS, and 22.04 LTS when the system uses Ubuntu-packaged kernels. Custom, mainline, or third-party kernels need headers from the same source that supplied the kernel, because Ubuntu’s default APT repositories only publish headers for Ubuntu kernel packages.
Install Linux Kernel Headers on Ubuntu
Choose the Ubuntu Kernel Header Package
Ubuntu does not provide a useful unversioned linux-headers package. Pick the exact header package or the tracking metapackage that matches your kernel policy:
| Package | Use Case | Update Behavior |
|---|---|---|
linux-headers-$(uname -r) | Installs headers for the kernel currently running now | Targets one kernel version only |
linux-headers-generic | Tracks Ubuntu’s GA kernel stack | Follows future GA kernel header updates |
linux-headers-generic-hwe-$RELEASE | Tracks Ubuntu’s HWE kernel stack for the current release | Can install or upgrade matching HWE kernel packages and headers |
build-essential and dkms | Adds compiler and DKMS tooling for third-party modules | Does not replace the matching header package |
Fedora and RHEL users often search for kernel-devel, while Debian users may know linux-headers-amd64. On Ubuntu, the normal module-build target is linux-headers-$(uname -r), plus linux-headers-generic or linux-headers-generic-hwe-$RELEASE when you want ongoing tracking.
Update Ubuntu Before Installing Headers
Refresh package metadata first, then review pending upgrades before installing headers. This prevents APT from targeting an older kernel package after your system already has newer kernel updates available.
sudo apt update
sudo apt upgrade
The install, update, and removal commands need administrator privileges. If your account cannot use
sudo, switch to an administrator account or follow the guide to add and manage sudo users on Ubuntu first.
If the upgrade installs a newer kernel, reboot before using $(uname -r). Otherwise, the command can look for headers for the old kernel that is still active in the current session.
sudo reboot
After the system comes back, confirm the active kernel version:
uname -r
Install Headers for the Running Ubuntu Kernel
Install the exact header package for the active kernel. This is the fastest fix when an installer says it cannot find kernel headers or the kernel source tree.
sudo apt install linux-headers-$(uname -r)
Verify that APT installed a header package for the same kernel reported by uname -r:
KERNEL="$(uname -r)"
if dpkg-query -W -f='${db:Status-Abbrev}\n' "linux-headers-$KERNEL" 2>/dev/null | grep -q '^ii'; then
echo "Matching header package is installed"
fi
test -d "/usr/src/linux-headers-$KERNEL" && echo "Matching header directory found"
A successful check returns both lines:
Matching header package is installed Matching header directory found
Install Header Tracking Metapackages
Use a tracking metapackage when this system should keep receiving matching kernel and header updates. Check which kernel track is already installed before adding another one:
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' 'linux-generic*' 'linux-headers-generic*' 2>/dev/null | grep '^ii'
For the GA kernel track, install the generic kernel and header metapackages together:
sudo apt install linux-generic linux-headers-generic
For the HWE kernel track, install the release-matched HWE metapackages. Keep the variable and install command in the same terminal session:
RELEASE="$(. /etc/os-release && echo "$VERSION_ID")"
sudo apt install "linux-generic-hwe-$RELEASE" "linux-headers-generic-hwe-$RELEASE"
HWE metapackages can install or upgrade kernel images, modules, tools, and headers as one stack. Reboot after that transaction, then verify
uname -rand the matching header directory again.
If you are not sure whether your system should use GA or HWE, compare the installed metapackages first. The HWE kernel guide for Ubuntu explains when the HWE stack is useful and how to switch intentionally.
Install Build Tools and DKMS for Drivers
Driver installers and local kernel modules often need more than headers. Install the compiler toolchain and DKMS when you are building modules for NVIDIA drivers on Ubuntu, VirtualBox on Ubuntu, Broadcom wireless drivers, or similar third-party module workflows.
sudo apt install linux-headers-$(uname -r) build-essential dkms
Check DKMS afterward:
dkms status
No output usually means no DKMS modules are registered yet. When a module is registered, the output should list the module name, version, kernel version, architecture, and an installed or built state.
Verify Linux Kernel Headers on Ubuntu
Ubuntu kernel versions move as updates land, so avoid copying a version string from another machine. Verify the active kernel, matching header package, header directory, and signing helper on the system you are fixing.
KERNEL="$(uname -r)"
printf 'Running kernel: %s\n' "$KERNEL"
if dpkg-query -W -f='${db:Status-Abbrev}\n' "linux-headers-$KERNEL" 2>/dev/null | grep -q '^ii'; then
echo "Matching header package is installed"
else
echo "Matching header package is missing"
fi
test -d "/usr/src/linux-headers-$KERNEL" && echo "Matching header directory found"
test -f "/usr/src/linux-headers-$KERNEL/scripts/sign-file" && echo "sign-file is available"
Successful output includes these stable status lines:
Matching header package is installed Matching header directory found sign-file is available
The scripts/sign-file path matters for signed module workflows, including Secure Boot setups. If that file is missing, reinstall the matching header package before rebuilding or signing a module.
Understand Linux Headers and DKMS on Ubuntu
linux-headers-$(uname -r) provides the files that match the active kernel ABI. Use it for immediate repairs, especially after an installer reports missing headers for the current kernel.
linux-headers-generic and linux-headers-generic-hwe-* are metapackages. They keep header updates aligned with the GA or HWE kernel track, which is better for long-lived workstations and systems that rebuild modules after kernel updates.
dkms rebuilds registered modules when kernel packages change, while build-essential provides the compiler and core build tools. They help module builds succeed, but neither package replaces the need for headers that match uname -r.
Troubleshoot Linux Kernel Headers on Ubuntu
Fix Unable to Locate linux-headers-$(uname -r)
If APT cannot locate the exact header package, the running kernel may be older than the package indexes, newer than your enabled repositories, or from a source outside Ubuntu’s normal kernel stack.
E: Unable to locate package linux-headers-6.8.0-100-generic
Check the active kernel and APT candidate:
uname -r
apt-cache policy "linux-headers-$(uname -r)"
A stale or unavailable kernel can show no candidate:
linux-headers-6.8.0-100-generic: Installed: (none) Candidate: (none)
Refresh metadata, reboot if a newer kernel is installed, then retry the matching header package:
sudo apt update
sudo reboot
After reconnecting, install headers for the now-active kernel:
sudo apt install linux-headers-$(uname -r)
If the candidate is still (none), confirm whether the kernel itself comes from Ubuntu’s repositories:
apt-cache policy "linux-image-$(uname -r)" "linux-headers-$(uname -r)"
For mainline, custom, or third-party kernels, install headers from that same kernel source or boot back into an Ubuntu-packaged kernel before using Ubuntu archive headers. If you use a packaged alternate kernel such as Liquorix, XanMod, or Zabbly, follow that kernel guide’s package and rollback path instead of forcing Ubuntu’s generic headers onto it.
Fix Package linux-headers-generic-hwe Is Not Configured Yet
An interrupted kernel transaction can leave HWE metapackages unpacked but not configured. Repair the package database first, then finish dependency resolution:
package linux-headers-generic-hwe-24.04 is not configured yet
sudo dpkg --configure -a
sudo apt --fix-broken install
Reinstall the HWE tracking packages for your release, then reboot and verify the matching header directory:
RELEASE="$(. /etc/os-release && echo "$VERSION_ID")"
sudo apt install "linux-generic-hwe-$RELEASE" "linux-headers-generic-hwe-$RELEASE"
sudo reboot
Fix DKMS Kernel Headers Cannot Be Found
DKMS reports missing headers when the active kernel lacks a matching header package or the compiler toolchain is incomplete. VirtualBox can show a related symptom when its kernel module is not built or loaded:
Error! Your kernel headers for kernel 6.17.0-23-generic cannot be found.
Kernel driver not installed (rc=-1908)
Check the three package roles DKMS normally needs:
for pkg in "linux-headers-$(uname -r)" build-essential dkms; do
dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' "$pkg" 2>/dev/null || echo "missing $pkg"
done
Install any missing pieces and trigger DKMS again:
sudo apt install linux-headers-$(uname -r) build-essential dkms
sudo dkms autoinstall
Then recheck module state:
dkms status
If the output still names a different kernel than uname -r, reboot into the target kernel or install headers for the kernel you are actually running.
Update Linux Kernel Headers on Ubuntu
Kernel headers update through normal APT maintenance. Update packages, reboot when the kernel changes, and then verify the active kernel and header package again. The broader Ubuntu package update guide covers APT maintenance in more detail.
sudo apt update
sudo apt upgrade
sudo reboot
After reboot, repeat the matching-header check:
KERNEL="$(uname -r)"
if dpkg-query -W -f='${db:Status-Abbrev}\n' "linux-headers-$KERNEL" 2>/dev/null | grep -q '^ii'; then
echo "Matching header package is installed"
else
echo "Matching header package is missing"
fi
test -d "/usr/src/linux-headers-$KERNEL" && echo "Matching header directory found"
If the check fails after a kernel update, install linux-headers-$(uname -r) for an immediate repair, then restore the GA or HWE tracking metapackage that matches your kernel track.
Remove Linux Kernel Headers from Ubuntu
Remove headers only when you no longer build modules for that kernel. APT can also remove kernel tracking metapackages during header removal, so simulate the transaction first and review the package list before confirming anything destructive. The Ubuntu package removal guide explains how to read APT removal output safely.
sudo apt -s remove linux-headers-$(uname -r)
If the simulated removal only affects the header packages you intend to remove, run the real removal:
sudo apt remove linux-headers-$(uname -r)
Do not run
sudo apt autoremoveblindly after kernel header removal. Review the proposed list first, especially on HWE systems where APT may include kernel images, kernel metapackages, or hardware-support packages.
Use a simulation before cleaning unused dependencies:
sudo apt -s autoremove
Restore headers for the running kernel at any time with:
sudo apt install linux-headers-$(uname -r)
Restore ongoing GA tracking with:
sudo apt install linux-generic linux-headers-generic
Restore ongoing HWE tracking with:
RELEASE="$(. /etc/os-release && echo "$VERSION_ID")"
sudo apt install "linux-generic-hwe-$RELEASE" "linux-headers-generic-hwe-$RELEASE"
Verify the restored state:
KERNEL="$(uname -r)"
if dpkg-query -W -f='${db:Status-Abbrev}\n' "linux-headers-$KERNEL" 2>/dev/null | grep -q '^ii'; then
echo "Matching header package is installed"
fi
Conclusion
Ubuntu now has kernel headers aligned with the active kernel, plus a safer path for GA or HWE tracking as future kernel updates arrive. With DKMS and build tools in place, driver workflows such as installing NVIDIA drivers on Ubuntu or installing VirtualBox on Ubuntu can rebuild modules against the right header tree.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>