Fix NVIDIA driver not loading on Ubuntu Server
nvidia-smi cannot talk to the driver. Walk the ladder: lsmod, dmesg, dkms status, then fix missing headers, nouveau, a kernel update or Secure Boot.
Why the NVIDIA driver is not loading on your Ubuntu server
nvidia-smi fails on a headless Ubuntu server because the NVIDIA driver's kernel module, nvidia.ko, is not loaded. The tool talks to the module through the /dev/nvidia* device nodes, and when the module is absent there is nothing on the other end. Four causes account for almost every case: the kernel headers were missing when DKMS tried to build the module, nouveau claimed the card first, a kernel update arrived before the module was rebuilt, or Secure Boot refused an unsigned module. Each one leaves a different message, so the fix starts with reading the right one.
This guide is for a machine with no display manager: a GPU VPS or a bare-metal box running Ubuntu 24.04 or 26.04. There is no X server and no login screen, so the whole question is whether the module loads and nvidia-smi answers. Every command below is one you run on your own machine. A container has no GPU and cannot load a kernel module, so none of this was checked by automation; the error strings are quoted from the NVIDIA and DKMS sources and from the Linux kernel, and the package names come from the Ubuntu archive as of September 2026.
Step 1: read what nvidia-smi actually says
Start with the tool that failed, because its wording narrows the search.
nvidia-smiThe message most readers see is this one:
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.That is the "module not loaded" case, and the rest of this ladder is for it. Two other messages mean something different.
Failed to initialize NVML: Driver/library version mismatch means a module is loaded, but it is an older build than the userspace libraries. NVML (NVIDIA Management Library) is what nvidia-smi links against. Ubuntu's documentation says this typically means the userspace packages were upgraded while the old kernel module stayed in memory, which is what an apt upgrade without a reboot does. Reboot, so the kernel loads the module that matches the libraries. Nothing else is broken.
No devices were found means the module loaded but did not claim any GPU. Ubuntu's documentation names nouveau as the usual reason, which is cause 2 below. You also get it from an -open driver package on a GPU older than Turing, covered in the packages section.
Step 2: check lsmod for nvidia and for nouveau
lsmod | grep -E '^(nvidia|nouveau)'
lspci -nn | grep -i nvidiaA healthy box lists nvidia, nvidia_uvm, nvidia_modeset and usually nvidia_drm. An empty result for nvidia confirms the module is not loaded. A line for nouveau tells you the open-source driver holds the card, and you can jump to cause 2.
If lspci prints nothing, there is no NVIDIA device on the PCI bus. On a VPS that means the plan does not include a GPU, or the passthrough is not configured, and nothing you do inside the guest will change it. What a GPU VPS actually gives you covers what to confirm with the provider before you touch a driver.
When lspci shows a card, ask which driver holds it:
lspci -nnk -d 10de:Kernel driver in use: nvidia is what you want. Kernel driver in use: nouveau is cause 2. No Kernel driver in use line at all means nothing has bound the device, which is the normal state when the module failed to build or failed to load.
Now load the module by hand, because the error modprobe prints is the single most useful line in this whole process:
sudo modprobe nvidiamodprobe: FATAL: Module nvidia not found in directory /lib/modules/7.0.0-31-generic means no nvidia.ko exists for the running kernel at all. That is cause 1 or cause 3. modprobe: ERROR: could not insert 'nvidia': Key was rejected by service, or the same line ending in Operation not permitted, is Secure Boot, cause 4. modprobe: ERROR: could not insert 'nvidia': No such device means the module's code loaded but its probe found no GPU it could take, which is nouveau or an unsupported card. Read dmesg next.
Step 3: read the driver's own messages in dmesg
sudo dmesg | grep -i -E 'nvrm|nvidia|nouveau|lockdown|unsigned'The NVIDIA module logs with an NVRM: prefix. When nouveau already owns the card, the driver source prints a block that includes these lines:
NVRM: The NVIDIA probe routine was not called for 1 device(s).
NVRM: This can occur when another driver was loaded and
NVRM: obtained ownership of the NVIDIA device(s).
NVRM: No NVIDIA devices probed.For Secure Boot, the kernel logs one of two lines. Loading of unsigned module is rejected appears when signature enforcement is on. Lockdown: modprobe: unsigned module loading is restricted; see man kernel_lockdown.7 appears when the kernel is in lockdown mode, which is the mode Ubuntu's kernel enters when it boots under Secure Boot.
If dmesg has nothing from NVRM: at all, the module never got as far as loading, and the story is in DKMS.
Step 4: ask DKMS what it built
DKMS (Dynamic Kernel Module Support) recompiles out-of-tree modules for each kernel you install. Ubuntu's nvidia-dkms-* packages register the driver with it.
dkms status
uname -r
ls -l /lib/modules/$(uname -r)/buildA healthy line reads nvidia-srv/580.178.04, 7.0.0-31-generic, x86_64: installed. The module name is nvidia-srv for the -server packages and nvidia for the desktop ones. Compare the kernel in that line with uname -r. If the only installed line names an older kernel than the one you are running, DKMS never built for the current kernel: cause 3. If the line ends in added instead of installed, or there is no line, the build failed or never ran: cause 1.
The ls -l line matters because /lib/modules/<kernel>/build is a symlink into /usr/src/linux-headers-<kernel>. When the link is dangling, the headers are not installed, and DKMS cannot build anything for that kernel.
An empty dkms status is not always bad. Ubuntu also ships pre-built modules in linux-modules-nvidia-* packages that never touch DKMS; dpkg -l 'linux-modules-nvidia*' shows whether you have one, and cause 3 explains how they go wrong.
Cause 1: the kernel headers were missing when the module was built
DKMS compiles nvidia.ko against the headers of the exact kernel that will load it. Without linux-headers-$(uname -r) the build cannot start, and each of the three tools involved announces this differently.
The nvidia-dkms-* package install prints, from DKMS's common postinst script:
Module build for kernel 7.0.0-31-generic was skipped since the kernel headers for this kernel do not seem to be installed.That line is not an error as far as apt is concerned. The package configures with exit code 0, and the driver is simply absent until you look. This is the most common way a fresh GPU VPS ends up with nvidia-smi failing on the first boot, when the image ships a kernel but not its headers.
Running dkms by hand is louder:
Error! Your kernel headers for kernel 7.0.0-31-generic cannot be found at /lib/modules/7.0.0-31-generic/build or /lib/modules/7.0.0-31-generic/source.
Please install the linux-headers-7.0.0-31-generic package or use the --kernelsourcedir option to tell DKMS where it's located.And NVIDIA's own .run installer reports it as the "kernel source tree" error:
Unable to find the kernel source tree for the currently running kernel. Please make sure you have installed the kernel source files for your kernel and that they are properly configured; on Red Hat Linux systems, for example, be sure you have the 'kernel-source' or 'kernel-devel' RPM installed. If you know the correct kernel source files are installed, you may specify the kernel source path with the '--kernel-source-path' command line option.The fix is the same in all three cases: install the headers for the running kernel, then build.
sudo apt update
sudo apt install -y linux-headers-$(uname -r)
sudo dkms autoinstall
sudo modprobe nvidia
nvidia-smidkms autoinstall builds every registered module for the running kernel. It ends with dkms autoinstall on 7.0.0-31-generic/x86_64 succeeded for nvidia-srv when it works. A failed for line points you at the build log, /var/lib/dkms/nvidia-srv/580.178.04/build/make.log, which is where a compiler error against a kernel the driver does not support shows up.
Install the headers metapackage too, so every future kernel brings its headers along: linux-headers-generic on the GA (general availability) kernel, or linux-headers-generic-hwe-24.04 if you run the HWE (hardware enablement) kernel on 24.04. Which of those you should be running is its own decision, and GA versus HWE kernel on Ubuntu Server lays out what each track changes under you.
Cause 2: nouveau still owns the card
nouveau is the in-tree open-source driver for NVIDIA cards. Ubuntu's kernel loads it automatically for any NVIDIA PCI ID it recognises, and once it has bound the device the proprietary module cannot take it. That is the NVRM: The NVIDIA probe routine was not called message above, and it is why nvidia-smi prints No devices were found while lsmod shows both drivers.
Ubuntu's driver packages ship a blacklist at /lib/modprobe.d/nvidia-graphics-drivers.conf, inside nvidia-kernel-common-*, which stops nouveau loading on the next boot. It still bites in two ways. You installed the driver and have not rebooted, so the nouveau from the old boot is still in memory. Or nouveau is inside the initramfs, where it loads before the root filesystem and its modprobe configuration exist. On a server whose console is on the card, rmmod nouveau fails with rmmod: ERROR: Module nouveau is in use because the framebuffer console holds it, so do not fight it. Blacklist, rebuild the initramfs, reboot.
cat /lib/modprobe.d/nvidia-graphics-drivers.conf
printf 'blacklist nouveau\noptions nouveau modeset=0\n' | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
sudo update-initramfs -u
sudo rebootAfter the reboot lsmod | grep nouveau must print nothing, and lspci -nnk -d 10de: should show Kernel driver in use: nvidia.
Cause 3: a kernel update outran the DKMS rebuild
When apt installs a new kernel, a hook at /etc/kernel/postinst.d/dkms rebuilds every DKMS module for it. That works only when the matching headers land in the same run, and only when the driver source compiles against the new kernel. Two things break it.
The first is the HWE kernel. On Ubuntu 24.04 the GA kernel is the 6.8 series, and as of September 2026 the HWE kernel is the 7.0 series that 26.04 ships. Move to HWE with only linux-image-generic-hwe-24.04 installed and you get a 7.0 kernel with no 7.0 headers. DKMS prints its was skipped line during the upgrade, and after the reboot modprobe nvidia answers Module nvidia not found in directory /lib/modules/7.0.0-31-generic, while dkms status still shows installed for the old 6.8 kernel and nothing for the new one.
The second is a driver branch too old for the new kernel. The build runs, fails, and DKMS reports Bad return status for module build on kernel: 7.0.0-31-generic (x86_64) followed by Consult /var/lib/dkms/nvidia-srv/580.178.04/build/make.log for more information. Ubuntu patches its own packages to keep building on the kernels it ships, so this mostly hits drivers from NVIDIA's CUDA repository or a .run install on a branch NVIDIA has stopped updating.
The fix for the first case is the headers, then a rebuild:
sudo apt install -y linux-headers-$(uname -r)
sudo dkms autoinstall
sudo modprobe nvidiaThen add the headers metapackage for your kernel track, so this is the last time. For the second case, move to a driver branch that supports the kernel, which the packages section covers.
There is a third variant that involves no DKMS at all. Ubuntu ships pre-built, Canonical-signed modules in linux-modules-nvidia-<branch>-<flavour> packages, and ubuntu-drivers install prefers them. Each one follows a kernel flavour: linux-modules-nvidia-580-server-generic tracks the GA kernel, and linux-modules-nvidia-580-server-generic-hwe-24.04 tracks the HWE one. If you switched kernel track and the modules package follows the other one, the new kernel has no module, and the fix is to install the package for the flavour you now run. When a pre-built module and a DKMS build exist for the same kernel at the same version, DKMS steps aside and prints DKMS will not replace this module., so the signed one is what loads.
If you need the GPU back in the next five minutes, boot the previous kernel from the GRUB menu; dkms status still shows installed for it, so the driver comes straight up. Booting the previous kernel and holding it walks through the GRUB menu on a VPS console and the apt-mark hold that keeps the next update from repeating this. The durable fix is to choose a kernel track deliberately. The GA kernel changes major version only when you decide to, which is what you want on a box whose whole job is a driver that must match the kernel. Cleaning up old kernels then stops DKMS rebuilding the module for four kernels you never boot.
Cause 4: Secure Boot rejects the unsigned module
Under UEFI Secure Boot, the Ubuntu kernel refuses any module that is not signed by a key it trusts. Canonical's key signs the kernel's own modules and the pre-built linux-modules-nvidia-* packages. A module DKMS compiled on your machine is signed, if at all, by a MOK (Machine Owner Key), and the kernel trusts that key only after you enroll it through the firmware.
This mostly bites bare metal. A KVM VPS usually boots with Secure Boot off, or in legacy BIOS mode where the question does not arise. Check before you spend time on it:
mokutil --sb-stateSecureBoot disabled or EFI variables are not supported on this system means this cause is not yours. SecureBoot enabled, together with the Key was rejected by service or Operation not permitted error from modprobe in step 2, means it is.
There are two ways out. The one Ubuntu recommends is to stop relying on DKMS for this driver and let ubuntu-drivers install put the signed pre-built package in place. The Ubuntu Server documentation says outright that the DKMS drivers "are not signed with Canonical's key and thus do not support secure boot".
The other is to enroll a MOK, which needs a console at boot. Ubuntu's DKMS signs modules with /var/lib/shim-signed/mok/MOK.priv when that key exists, and update-secureboot-policy from the shim-signed package creates and enrolls it:
sudo update-secureboot-policy --new-key
sudo update-secureboot-policy --enroll-key
mokutil --test-key /var/lib/shim-signed/mok/MOK.der--enroll-key asks for a one-time password. On the next boot, shim shows a blue "Perform MOK management" screen before Linux starts, and you choose "Enroll MOK" and type that password. SSH is not up at that point, so on a bare-metal server you need IPMI or a KVM-over-IP console. Until the key is enrolled, mokutil --test-key prints is not enrolled and every DKMS-signed module stays rejected. After enrolling, run sudo dkms autoinstall so the module is rebuilt and signed with the now-trusted key.
Which package to install: ubuntu-drivers and the -server branch
Ubuntu's own packages are the right tool on 24.04 and on 26.04. Let the detection tool say what fits your card:
sudo apt install -y ubuntu-drivers-common
sudo ubuntu-drivers list --gpgpuThe list shows names like nvidia-driver-580-server and nvidia-driver-580-server-open, alongside the desktop ones without -server. The suffixes mean different things.
Plain nvidia-driver-580 is the UDA (Unified Driver Architecture) branch, which Ubuntu recommends for desktops. -server is the ERD (Enterprise Ready Driver) branch, the same driver on NVIDIA's production support cadence, which Ubuntu recommends for servers and compute. On a headless box use -server. -open builds the module from NVIDIA's open-source kernel module code, which NVIDIA's README says "can be used on any Turing or later GPU". On a Pascal or Volta card the open module finds no GPU it supports, logs NVRM: No NVIDIA devices probed., and modprobe returns No such device. If lspci names a GTX 10-series or a Tesla P-series card, do not pick -open.
As of September 2026 the 24.04 archive carries -server branches 570, 580 and 590 in restricted, and 26.04 ships 580-server at the same 580.178.04 release as 24.04. Install with the --gpgpu flag, which selects the -server set:
sudo ubuntu-drivers install --gpgpu nvidia:580-server
sudo rebootubuntu-drivers installs the pre-built signed linux-modules-nvidia-580-server-<flavour> package for the kernel flavour you run, together with the nvidia-driver-580-server metapackage. That metapackage also depends on nvidia-dkms-580-server, so DKMS is registered as well and serves as the fallback for a kernel the pre-built package does not cover yet, provided the headers are there. The Ubuntu documentation recommends against DKMS-only installs unless you run a custom kernel, and reserves --include-dkms for that case.
After the reboot:
nvidia-smi
cat /proc/driver/nvidia/versionnvidia-smi should print its table with the driver version and your card. /proc/driver/nvidia/version prints the kernel module's own version line, and it must match the driver version in the nvidia-smi header; a mismatch is the Driver/library version mismatch case, and one more reboot fixes it.
If a wrong or half-installed driver is already present, remove it first. Ubuntu's documented command is sudo apt --purge remove '*nvidia*580*' followed by sudo apt autoremove, with the branch number changed to match whatever dkms status and dpkg -l | grep nvidia show.
Why NVIDIA's .run installer is the wrong tool here
The NVIDIA-Linux-x86_64-<version>.run file from NVIDIA's site compiles the module on the spot and copies libraries over the filesystem outside of apt. Three things follow. apt does not know about those files, so the next upgrade that touches libnvidia-* or a kernel overwrites half of them, and you get the version mismatch error on a box that was fine yesterday. The module it builds is unsigned, so under Secure Boot it needs the MOK enrollment above. And its headers check is the Unable to find the kernel source tree error, which the Ubuntu package would have avoided by depending on the headers for you.
The .run file is the right tool when you need a driver version Ubuntu has not packaged and you accept running nvidia-uninstall before every distribution driver upgrade. If you need a newer branch than the archive carries, NVIDIA's CUDA apt repository is the better path, because it is still apt. On a mixed box, pick one source and purge the other, because two copies of libnvidia-* is exactly how the mismatch error appears.
Make the driver survive the next kernel update
Everything above is recovery. Three habits stop it recurring.
- Keep a headers metapackage installed that matches your kernel metapackage:
linux-headers-genericwithlinux-image-generic, or the-hwe-24.04pair on 24.04. Check withdpkg -l 'linux-headers-generic*' 'linux-image-generic*'. - Keep the pre-built
linux-modules-nvidia-<branch>-<flavour>package for the same flavour, so a signed module arrives with every kernel and DKMS is only the fallback. - Decide GA or HWE once and stay on it. A GPU box that switches kernel track is a GPU box that loses its driver on the next reboot.
Then, after every kernel update and before you reboot, check that the driver will be there:
dkms status
dpkg -l 'linux-modules-nvidia*' | grep '^ii'You want an installed line for the new kernel version, or a linux-modules-nvidia-* package that names it. If you see neither, run sudo dkms autoinstall -k <new kernel version> before the reboot, not after it.
Once nvidia-smi answers, the GPU is ready for whatever the box is for. Running Ollama on a GPU VPS and NVENC hardware transcoding in Jellyfin both start from the point where nvidia-smi shows the card, and both fail with the same silence when it does not.
FAQ
Why does nvidia-smi say it couldn't communicate with the NVIDIA driver?
Because the nvidia kernel module is not loaded. Run lsmod | grep nvidia; an empty result confirms it. Then run sudo modprobe nvidia and read the error. Module nvidia not found in directory means no module was built for this kernel, so the headers were missing or a kernel update arrived first. Key was rejected by service is Secure Boot refusing an unsigned module. No such device means nouveau holds the card or the driver package does not support it. dkms status then shows which kernels have a build at all.
Do I need linux-headers to install the NVIDIA driver on Ubuntu?
For the DKMS packages, yes, and they must be the headers for the exact running kernel, linux-headers-$(uname -r). Without them the nvidia-dkms-* package prints Module build for kernel ... was skipped since the kernel headers for this kernel do not seem to be installed and still exits successfully, so nothing looks wrong until nvidia-smi fails. Keep linux-headers-generic, or the HWE equivalent, installed so future kernels bring their headers. The pre-built linux-modules-nvidia-* packages need no headers because Canonical compiled and signed them already.
What is the difference between nvidia-driver-580, -server and -open?
nvidia-driver-580 is the desktop branch. nvidia-driver-580-server is the enterprise branch on NVIDIA's production support cadence, which Ubuntu recommends for servers and compute, and it is the one to use on a headless box. The -open suffix builds the module from NVIDIA's open-source kernel module code, which NVIDIA states works on Turing and newer GPUs. On a Pascal or Volta card the open module finds nothing to drive, so stay with the non-open package there.
The NVIDIA driver stopped working after a kernel update. How do I get it back?
Fastest: boot the previous kernel from the GRUB menu, where dkms status still shows the module installed. Proper: install linux-headers-$(uname -r) for the new kernel, run sudo dkms autoinstall, then sudo modprobe nvidia. If DKMS reports Bad return status for module build, the driver branch does not support the new kernel, and you need a newer -server branch. If you use the pre-built linux-modules-nvidia-* packages, install the one for the kernel flavour you now run, generic or generic-hwe-24.04. Then pick GA or HWE deliberately and stay there.
Do I need to worry about Secure Boot on a VPS?
Usually not. Run mokutil --sb-state. SecureBoot disabled or EFI variables are not supported on this system rules it out, and that is the answer on most KVM instances. On bare metal with SecureBoot enabled, either install the Canonical-signed pre-built modules through ubuntu-drivers install, or create and enroll a MOK with update-secureboot-policy, which needs a console at boot to confirm the enrollment.