Cleaning Up Old Kernels on Linux
Guide to safely removing old Linux kernels to free disk space, including manual cleanup, automatic configuration, and recovery procedures.
Cleaning Up Old Kernels on Linux
Linux keeps old kernels as fallback options, but they accumulate and consume significant disk space. My /boot partition was 100% full with 15 old kernels. This guide covers safe kernel cleanup on Ubuntu/Debian systems.
Environment
- OS: Ubuntu 22.04 LTS
- Current kernel: 5.15.0-84-generic
- Problem: /boot partition full
$ uname -r
5.15.0-84-generic
$ df -h /boot
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 512M 512M 0 100% /bootThe Problem
$ ls -la /boot/vmlinuz-* | wc -l
15
# Too many kernels consuming all boot space
$ ls -la /boot/vmlinuz-*
-rw-r--r-- 1 root root 11M Jun 25 2024 vmlinuz-5.15.0-25-generic
-rw-r--r-- 1 root root 11M Jul 15 2024 vmlinuz-5.15.0-50-generic
-rw-r--r-- 1 root root 11M Aug 20 2024 vmlinuz-5.15.0-56-generic
-rw-r--r-- 1 root root 11M Sep 30 2024 vmlinuz-5.15.0-67-generic
-rw-r--r-- 1 root root 11M Oct 15 2024 vmlinuz-5.15.0-73-generic
-rw-r--r-- 1 root root 11M Nov 20 2024 vmlinuz-5.15.0-76-generic
-rw-r--r-- 1 root root 11M Dec 10 2024 vmlinuz-5.15.0-78-generic
-rw-r--r-- 1 root root 11M Jan 15 2025 vmlinuz-5.15.0-79-generic
-rw-r--r-- 1 root root 11M Feb 28 2025 vmlinuz-5.15.0-82-generic
-rw-r--r-- 1 root root 11M Mar 20 2025 vmlinuz-5.15.0-83-generic
-rw-r--r-- 1 root root 11M Apr 15 2025 vmlinuz-5.15.0-84-generic
# Cannot install new updates
$ sudo apt update
E: You don't have enough free space in /var/cache/apt/archives/Analysis
Step 1: Check Installed Kernels
# List installed kernels
$ dpkg -l linux-image-* | grep ^ii
ii linux-image-5.15.0-25-generic 5.15.0-25.25 amd64 Signed kernel image generic
ii linux-image-5.15.0-50-generic 5.15.0-50.56 amd64 Signed kernel image generic
ii linux-image-5.15.0-56-generic 5.15.0-56.62 amd64 Signed kernel image generic
ii linux-image-5.15.0-76-generic 5.15.0-76.83 amd64 Signed kernel image generic
ii linux-image-5.15.0-84-generic 5.15.0-84.94 amd64 Signed kernel image generic
# Check current running kernel
$ uname -r
5.15.0-84-genericStep 2: Calculate Space Usage
# Size of kernel files
$ du -sh /boot/
512M /boot/
# Size per kernel version
$ for ver in $(ls /boot/vmlinuz-* | sed 's/.*vmlinuz-//'); do
echo "$ver: $(du -sh /boot/*$ver* 2>/dev/null | awk '{sum += $1} END {print sum}')"
doneSolution
Fix 1: Use apt autoremove (Recommended)
# Automatically remove old kernels
$ sudo apt autoremove --purge
# This removes kernels not currently running and not marked as manual
Reading package lists... Done
The following packages will be REMOVED:
linux-image-5.15.0-25-generic
linux-image-5.15.0-50-generic
linux-image-5.15.0-56-generic
linux-image-5.15.0-76-generic
linux-image-5.15.0-78-generic
linux-image-5.15.0-79-generic
linux-image-5.15.0-82-generic
linux-image-5.15.0-83-generic
0 upgraded, 8 newly removed, 0 to upgrade and 0 not to upgrade.
# Verify space freed
$ df -h /boot
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 512M 128M 384M 25% /bootFix 2: Manually Remove Specific Kernels
# Remove specific kernel version
$ sudo apt purge linux-image-5.15.0-25-generic linux-image-5.15.0-50-generic
# Remove all kernels except current
$ CURRENT=$(uname -r)
$ dpkg -l linux-image-* | grep ^ii | awk '{print $2}' | \
grep -v "$CURRENT" | xargs sudo apt purge -y
# Update GRUB
$ sudo update-grubFix 3: Configure Automatic Cleanup
# Set to keep only 2 kernels
$ echo 'GRUB_DEFAULT="saved"' | sudo tee -a /etc/default/grub
$ echo 'GRUB_SAVEDEFAULT=true' | sudo tee -a /etc/default/grub
# Or use synaptic for GUI management
$ sudo apt install synapticFix 4: Clean Boot Cache
# Remove old initrd images
$ sudo find /boot -name "initrd.img-*" -mtime +30 -delete
# Remove old System.map files
$ sudo find /boot -name "System.map-*" -mtime +30 -delete
# Clean GRUB cache
$ sudo grub-mkconfig -o /boot/grub/grub.cfgConfigure Automatic Kernel Cleanup
# Create script for automated cleanup
$ sudo cat > /usr/local/bin/cleanup-kernels.sh << 'EOF'
#!/bin/bash
KEEP_KERNELS=2
CURRENT=$(uname -r)
# Get list of installed kernels
INSTALLED=$(dpkg -l linux-image-* | grep ^ii | awk '{print $2}' | \
sed 's/linux-image-//' | sort -V)
# Count kernels
COUNT=$(echo "$INSTALLED" | wc -l)
if [ "$COUNT" -gt "$KEEP_KERNELS" ]; then
REMOVE_COUNT=$((COUNT - KEEP_KERNELS))
echo "Removing $REMOVE_COUNT old kernels..."
echo "$INSTALLED" | head -n "$REMOVE_COUNT" | while read kernel; do
if [ "$kernel" != "$CURRENT" ]; then
sudo apt purge -y "linux-image-${kernel}"
fi
done
sudo update-grub
fi
EOF
$ sudo chmod +x /usr/local/bin/cleanup-kernels.sh
# Add to weekly cron
$ sudo crontab -e
0 3 * * 0 /usr/local/bin/cleanup-kernels.sh >> /var/log/kernel-cleanup.log 2>&1Verify Cleanup
# Check remaining kernels
$ dpkg -l linux-image-* | grep ^ii
ii linux-image-5.15.0-83-generic 5.15.0-83.93 amd64 Signed kernel image generic
ii linux-image-5.15.0-84-generic 5.15.0-84.94 amd64 Signed kernel image generic
# Check boot space
$ df -h /boot
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 512M 128M 384M 25% /boot
# Verify GRUB works
$ sudo update-grub
Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.15.0-84-generic
Found initrd image: /boot/initrd.img-5.15.0-84-genericLessons Learned
- Always keep current kernel + one fallback - never remove the running kernel.
- Use
apt autoremove --purgefor safest automatic cleanup. - Monitor /boot space - it fills up faster than root partition.
- Update GRUB after manual removal to avoid boot menu errors.
- Test boot after cleanup - ensure the system boots correctly with remaining kernels.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.