There’s a specific kind of satisfaction in cleanly unloading a kernel module you no longer need — no reboot, no service restart, just the kernel handing back that memory and reference immediately. rmmod is the direct, no-frills tool for that job. It’s the mirror image of insmod: simple, low-level, and completely honest about exactly what it will and won’t do for you.
What rmmod Actually Is
rmmod removes a single, currently-loaded kernel module from the running kernel. Like its counterpart insmod, it operates directly on one named module and does not perform any dependency resolution — if other modules currently depend on the one you’re trying to remove, rmmod simply refuses and tells you so, rather than trying to figure out and remove the whole chain for you (that’s exactly the job modprobe -r does instead).
Basic Syntax
rmmod [options] module_name [module_name ...]
You need root privileges, since unloading kernel code is a privileged operation.
A Basic Example
sudo rmmod vfat
No output on success. Verify:
lsmod | grep vfat
If nothing is printed, it’s gone.
Full Option Reference
-f, --force force unload, ignoring usage count and taint warnings (dangerous)
-s, --syslog print messages to syslog instead of stderr
-v, --verbose print extra information about what's happening
-w, --wait wait until the module is no longer used, then remove it
-h, --help display help
-V, --version print version
Removing Multiple Modules
sudo rmmod module_a module_b
Each is processed independently — if one fails (e.g., still in use), rmmod reports the error for that one but still attempts the others.
Verbose Output
sudo rmmod -v vfat
rmmod: unloading vfat...
Waiting for a Module to Become Unused
sudo rmmod -w some_module
Rather than failing immediately if the module currently shows a non-zero “used by” count, -w makes rmmod block and wait until the usage count drops to zero (e.g., once whatever process or filesystem is using it finishes and releases it), then removes it. Useful in scripted maintenance windows where you know something will finish shortly and you don’t want a hard failure.
Force Removal (Genuinely Dangerous)
sudo rmmod -f some_module
This bypasses the normal usage-count safety check and tries to unload the module anyway. This can crash the kernel or corrupt kernel memory state if anything is still actively using that module’s code or data structures — it should be treated as an absolute last resort in a debugging/recovery context, never as a routine way to work around “module is busy” errors. If a module genuinely won’t unload normally, the right move is almost always to find and stop whatever is using it first, not to force the unload.
The “Used By” Check
Before removing anything, rmmod checks the module’s reference count — visible directly via lsmod:
lsmod | grep fat
vfat 24576 0
fat 98304 1 vfat
Here, fat shows 1 vfat, meaning the vfat module currently depends on it. Attempting to remove fat directly will fail:
sudo rmmod fat
rmmod: ERROR: Module fat is in use by: vfat
The correct order is to remove the dependent first:
sudo rmmod vfat
sudo rmmod fat
Or, more conveniently, let modprobe -r handle this dependency-aware removal automatically:
sudo modprobe -r vfat
(modprobe -r will also remove fat afterward automatically, since it becomes unused once vfat is gone — something plain rmmod will never do on its own.)
Why a Module Might Refuse to Unload Even With a Zero “Used By” Count
Beyond the module-dependency reference count, a module can also be held in use by:
- Open file descriptors referencing something the module provides (e.g., an open file on a filesystem type it implements).
- Active hardware still attached and initialized by that driver.
- The module being marked as unremovable at compile time (some drivers deliberately don’t support unloading at all, particularly certain core subsystems or drivers with irreversible hardware initialization steps).
sudo rmmod e1000e
rmmod: ERROR: Module e1000e is in use
Checking lsusb/lspci and dmesg, plus confirming no network interface is still up and using that driver (ip link and checking the interface’s driver via ethtool -i eth0), is usually the next diagnostic step.
Real-World System Administration Examples
Safely unloading a module and verifying, as part of a maintenance script:
#!/bin/bash
MOD="old_driver"
if lsmod | grep -q "^${MOD} "; then
if sudo rmmod "$MOD"; then
echo "Successfully removed $MOD"
else
echo "Failed to remove $MOD — check lsmod for dependents"
lsmod | grep "^${MOD} "
exit 1
fi
else
echo "$MOD is not currently loaded, nothing to do."
fi
Unloading a whole dependency chain manually (illustrating exactly what modprobe -r automates for you):
lsmod | grep vfat
vfat 24576 0
sudo rmmod vfat
lsmod | grep "^fat "
fat 98304 0
sudo rmmod fat
Reloading a misbehaving driver (common troubleshooting pattern for flaky hardware):
sudo rmmod e1000e && sudo modprobe e1000e
This forces a clean re-initialization of the driver and its associated hardware state, which resolves a surprising number of “device stopped responding” issues without a full reboot.
Waiting for a busy module to free up during a scheduled maintenance window:
sudo rmmod -w -v nf_conntrack
Troubleshooting
“rmmod: ERROR: Module X is in use by: Y, Z” — remove Y and Z first, or use modprobe -r X to handle the whole chain automatically.
“rmmod: ERROR: Module X is not currently loaded” — check spelling and confirm with lsmod | grep X — you can’t remove what isn’t loaded.
“rmmod: ERROR: Module X is in use” with no dependents listed — something outside the module dependency system (an open file, an active hardware attachment) is holding a reference; investigate with lsof, check mounted filesystems using that module type, or check dmesg for related driver activity.
System becomes unstable or crashes after a forced removal — this is exactly the risk -f/--force carries; avoid it outside of genuinely last-resort debugging scenarios, and expect that a forced unload of a module still actually in use can corrupt kernel memory or cause a kernel panic.
Security and Stability Considerations
- Avoid
-f/--forcein any production context; treat it the way you’d treatkill -9on a process that won’t die cleanly — a last resort with real consequences, not a routine shortcut. - Prefer
modprobe -rover manually chainingrmmodcalls for anything with a non-trivial dependency chain; it’s both safer (correct removal order, automatically) and less error-prone than doing it by hand. - On systems with
kernel.modules_disabled=1set (module loading locked down after boot for security hardening),rmmodis typically still permitted for removal (since removing code reduces attack surface rather than adding it), but this depends on kernel configuration and should be verified in your specific hardened environment rather than assumed. - Regularly unloading and reloading modules in production as a troubleshooting technique is reasonable for isolated driver issues, but repeated unexplained module instability (needing frequent
rmmod/modprobecycles to keep hardware working) is itself a signal worth investigating further — a failing NIC, a driver bug, or a firmware mismatch, rather than something to just paper over with periodic reloads.
Comparison to Related Commands
modprobe -r— the dependency-aware equivalent; removes a module and any now-unused dependencies automatically, in the correct order. Preferred for anything beyond a single standalone module.insmod— the loading counterpart; also has zero dependency awareness, mirroringrmmod‘s behavior on the removal side.lsmod— essential companion for checking a module’s current usage count before attempting removal.modinfo— useful for confirming what a module actually does before deciding it’s safe to remove, though it doesn’t show live usage state (that’slsmod‘s job).
rmmod‘s core behavior and options are consistent across Debian, Ubuntu, RHEL, CentOS, Fedora, SUSE, and Arch, since it’s part of the same universally-adopted kmod toolkit.
Summary
rmmod does exactly one thing — remove a single named, currently-loaded kernel module — and does it honestly, refusing outright if anything still depends on it rather than silently doing something risky. For anything involving a dependency chain, reach for modprobe -r instead; reserve -f/--force for genuine last-resort debugging, and always check lsmod‘s “Used by” column before you even try.
References
man rmmodon your local systemkmodproject documentation- Linux Kernel Module Programming Guide (kernel.org)