I try to do do-release-upgrade but then I get:

Not enough free disk space

The upgrade has aborted. The upgrade needs a total of 25.7 M free space on disk '/boot'. Please free at least an additional 25.7 M of disk space on '/boot'. Empty your trash and remove temporary packages of former installations using 'sudo apt-get clean'.

Output of df:

                    237251272 214797108  10402504  96% /
udev                    488120         4    488116   1% /dev
tmpfs                   198676       668    198008   1% /run
none                      5120         0      5120   0% /run/lock
none                    496684         0    496684   0% /run/shm
/dev/sda1               233191    225867         0 100% /boot

How come there is no space left on boot? Here's the output of ls -as /boot:

total 221839
    4 .
    4 ..
  645 abi-2.6.32-34-generic-pae
  698 abi-2.6.35-30-generic-pae
  727 abi-2.6.38-12-generic-pae
  727 abi-3.0.0-12-generic-pae
  727 abi-3.0.0-13-generic-pae
  727 abi-3.0.0-14-generic-pae
  727 abi-3.0.0-15-generic-pae
  727 abi-3.0.0-16-generic-pae
  727 abi-3.0.0-17-generic-pae
  727 abi-3.0.0-19-generic-pae
  761 abi-3.0.0-20-generic-pae
  115 config-2.6.32-34-generic-pae
  128 config-2.6.35-30-generic-pae
  136 config-2.6.38-12-generic-pae
  140 config-3.0.0-12-generic-pae
  140 config-3.0.0-13-generic-pae
  140 config-3.0.0-14-generic-pae
  140 config-3.0.0-15-generic-pae
  140 config-3.0.0-16-generic-pae
  140 config-3.0.0-17-generic-pae
  140 config-3.0.0-19-generic-pae
  140 config-3.0.0-20-generic-pae
    5 grub
10773 initrd.img-2.6.32-34-generic-pae
13619 initrd.img-2.6.35-30-generic-pae
15365 initrd.img-2.6.38-12-generic-pae
16481 initrd.img-3.0.0-12-generic-pae
16487 initrd.img-3.0.0-13-generic-pae
16501 initrd.img-3.0.0-14-generic-pae
16476 initrd.img-3.0.0-15-generic-pae
16481 initrd.img-3.0.0-16-generic-pae
16478 initrd.img-3.0.0-17-generic-pae
   12 lost+found
  174 memtest86+.bin
  176 memtest86+_multiboot.bin
 1700 System.map-2.6.32-34-generic-pae
 1841 System.map-2.6.35-30-generic-pae
 2115 System.map-2.6.38-12-generic-pae
 2141 System.map-3.0.0-12-generic-pae
 2141 System.map-3.0.0-13-generic-pae
 2143 System.map-3.0.0-14-generic-pae
 2146 System.map-3.0.0-15-generic-pae
 2147 System.map-3.0.0-16-generic-pae
 2147 System.map-3.0.0-17-generic-pae
 2148 System.map-3.0.0-19-generic-pae
 2149 System.map-3.0.0-20-generic-pae
    2 vmcoreinfo-2.6.32-34-generic-pae
    2 vmcoreinfo-2.6.35-30-generic-pae
    2 vmcoreinfo-2.6.38-12-generic-pae
    2 vmcoreinfo-3.0.0-12-generic-pae
    2 vmcoreinfo-3.0.0-13-generic-pae
    2 vmcoreinfo-3.0.0-14-generic-pae
    2 vmcoreinfo-3.0.0-15-generic-pae
    2 vmcoreinfo-3.0.0-16-generic-pae
    2 vmcoreinfo-3.0.0-17-generic-pae
    2 vmcoreinfo-3.0.0-19-generic-pae
    2 vmcoreinfo-3.0.0-20-generic-pae
 4092 vmlinuz-2.6.32-34-generic-pae
 4347 vmlinuz-2.6.35-30-generic-pae
 4567 vmlinuz-2.6.38-12-generic-pae
 4675 vmlinuz-3.0.0-12-generic-pae
 4676 vmlinuz-3.0.0-13-generic-pae
 4681 vmlinuz-3.0.0-14-generic-pae
 4698 vmlinuz-3.0.0-15-generic-pae
 4700 vmlinuz-3.0.0-16-generic-pae
 4700 vmlinuz-3.0.0-17-generic-pae
 4703 vmlinuz-3.0.0-19-generic-pae
 4705 vmlinuz-3.0.0-20-generic-pae

Output of uname -a:

 Linux kitsch 3.0.0-17-generic-pae #30-Ubuntu SMP Thu Mar 8 17:53:35 UTC 2012 i686 i686 i386 GNU/Linux
  • Add the output to ls -l /boot and uname -a to your question. – jippie May 27 '12 at 14:51
  • Also add the output to dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' to your question. – jippie May 27 '12 at 14:57
  • ls -as /boot might be useful instead. It will include just the sizes of the files. – adempewolff May 27 '12 at 15:01
  • the output of ls -l /boot is quite long too post here so here is a pastebin pastebin.com/yM1aEJUx – clamp May 27 '12 at 15:02
  • 5
    No it is not. It is the cause of your problem. If your question is indeed getting too long someone will edit it. Use of external services like pastebin will break the value of the question for future reference. – jippie May 27 '12 at 15:03

Your /boot partition is filled with old kernels. It does that sometimes, not sure why it is never fixed. You can easily remove the old kernels if you know which packages they came in.

First check uname -a to check your current version.

Then run the following command:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

This command will list all packages that you no longer need. I don't like removing them automatically, I like to be in control when it comes to removing kernels. So for every package listed do the following:

sudo apt-get -y purge some-kernel-package


This intermezzo describes in more detail how the commands work and tries to fix an issue with linux-libc-dev:amd64. Most users can skip this paragraph.

  • dpkg -l 'linux-*' list all packages that have a name starting with 'linux-'
  • sed '/^ii/!d; remove all lines that do *not* start withii`
  • uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/" find the current running kernel version
  • /'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d Remove all lines, except the ones containing the current running kernel version number
  • s/^[^ ]* [^ ]* \([^ ]*\).*/\1/ For each line list only the package name
  • /[0-9]/!d Remove lines that do not contain numbers.

To fix Frederick Nord's issue I think the command can be amended as follows:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d;/^linux-\(headers\|image\)/!d'

It basically adds an extra filter:

  • /^linux-(headers\|image)/!d Delete all lines that do not start with linux-headers or linux-image


Where some-kernel-package can be replaced with one of the packages listed. Just beware that you don't remove the kernel packages that are in current use (as listed by the uname -a) eg. sudo apt-get purge -y linux-headers-3.0.0-12 etc.

It can be automated further using the xargs command, but I don't like that. It is a personal thing. However, here's the command to do so:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge

This is what my /boot looks like, one spare kernel (2.6.38-11) just in case and 3.2.0-24 being current:

$ ls -l /boot
total 59388
-rw-r--r-- 1 root root   730545 Sep 13  2011 abi-2.6.38-11-generic
-rw-r--r-- 1 root root   791023 Apr 25 13:51 abi-3.2.0-24-generic
-rw-r--r-- 1 root root   130326 Sep 13  2011 config-2.6.38-11-generic
-rw-r--r-- 1 root root   140341 Apr 25 13:51 config-3.2.0-24-generic
drwxr-xr-x 3 root root     5120 May 27 17:46 grub
-rw-r--r-- 1 root root 20883146 Oct  1  2011 initrd.img-2.6.38-11-generic
-rw-r--r-- 1 root root 22474219 May  5 09:04 initrd.img-3.2.0-24-generic
drwxr-xr-x 2 root root    12288 Apr 16  2009 lost+found
-rw-r--r-- 1 root root   176764 Nov 27 11:00 memtest86+.bin
-rw-r--r-- 1 root root   178944 Nov 27 11:00 memtest86+_multiboot.bin
-rw------- 1 root root  2656297 Sep 13  2011 System.map-2.6.38-11-generic
-rw------- 1 root root  2884358 Apr 25 13:51 System.map-3.2.0-24-generic
-rw------- 1 root root     1369 Sep 13  2011 vmcoreinfo-2.6.38-11-generic
-rw------- 1 root root  4526784 Sep 13  2011 vmlinuz-2.6.38-11-generic
-rw------- 1 root root  4965776 Apr 25 13:51 vmlinuz-3.2.0-24-generic

And file system usage:

$ df -h /boot
Filesystem Size Used Avail Use% Mounted
/dev/sda5  228M  63M  154M  29% /boot
  • 2
    This solution was heavily inspired on an article by OzzyFrank at ubuntugenius.wordpress.com/2011/01/08/… – jippie May 27 '12 at 15:37
  • 6
    Yes, why is this an issue is the question? This shouldn't be on the user to handle. – Elijah Lynn Nov 1 '13 at 20:58
  • 2
    FWIW: This also matched linux-libc-dev:amd64 for me. So it may very well be a little too generous. – Frederick Nord May 1 '14 at 13:30
  • 4
    It does that sometimes, not sure why it is never fixed Ubuntu has made the decision, for better or worse, to provide regular new kernels as new packages rather than as upgrades to existing packages, to give the option of having multiple kernels installed and switching between them at will. I agree that this assumption doesn't suit the 95% of people who just want the latest kernel (and maybe one fallback in case of new boot problems), and who don't want to manage the installed kernels themself. Perhaps in the future Ubuntu will change this behaviour. For now, make sure your /boot is huge. – thomasrutter Jul 30 '14 at 11:19
  • 1
    @thomasrutter If you (like me and the 95% of people you are talking about) think this bug is important, vote on it here: bugs.launchpad.net/ubuntu/+source/update-manager/+bug/1183692 – FriendFX Oct 12 '16 at 11:24

sudo apt-get autoremove

did the trick for me, it cleaned up successfully all the unused kernel packages.

  • 3
    this is not correct. from man apt-get autoremove is used to remove packages that were automatically installed to satisfy dependencies for some package and that are no more needed. a kernel would not be installed to satisfy dependencies, they are installed during upgrades. – dward May 30 '14 at 21:44
  • 5
    @neon_overload I just posted it because it did the trick, for me. – topless Jul 30 '14 at 14:20
  • 1
    @dward It did free some space for me : before autremove : /dev/sda1, 240M total, 171M used, 57M free, 75% used /boot after: /dev/sda1, 240M total, 129M used, 98M free, 57% used /boot – Stefan Rogin May 8 '15 at 8:39
  • @clickstefan the first answer is correct. see also askubuntu.com/questions/89710/… – dward May 14 '15 at 12:39
  • 4
    There should be a button to perform this task in the "Not enough free disk space" dialogue. This would especially help novice users that are not familiar with the command line. – Martin R. Jan 6 '16 at 21:28

Equivalent to the accepted answer -- another (possibly) easier way is to install the ubuntu-tweak tool, it can be downloaded from here. Go to "Janitor", and select "Old Kernel" to clean. It can be done in a few clicks. (tested on 14.04 desktop)

enter image description here

  • Situation with lack of space on /boot happens all the time so this is my favourite solution - easy to run application that does the job with one click. – s3m3n Dec 28 '15 at 12:33

Compared to other GUI answers here, the advantage of this answer is native Ubuntu Bash is used without installing third-party applications.

Zenity and Bash based solution

Zenity provides a nice GUI interface to the terminal to process a list and select items with radio-buttons:

rm-kernels 1

The current kernel you booted with cannot be removed and isn't included in the list. The size reported is how much will be saved in /boot directory. More is saved on your disk because kernel binaries reside in other areas too. July 27, 2017 note: The directories /usr/src/*kernel_version* and /lib/modules/*kernel_version* are now included as well.

The Modified Date is discovered using the stat command. On my system that date is "touched" every time the kernel is booted using this (How do you find out when a specific kernel version was last booted?) cron reboot script. However, on your system the date will be the kernel release date, not the last time you booted it.

apt-get purge gives you chance to abort

You are given a final opportunity to view everything that will be purged and see the total disk space (somewhat misleading) that will be recovered:

The following packages will be REMOVED:
  linux-headers-4.7.1-040701* linux-headers-4.7.1-040701-generic*
  linux-headers-4.7.2-040702* linux-headers-4.7.2-040702-generic*
  linux-headers-4.7.3-040703* linux-headers-4.7.3-040703-generic*
  linux-headers-4.8.1-040801* linux-headers-4.8.1-040801-generic*
  linux-headers-4.8.10-040810* linux-headers-4.8.10-040810-generic*
  linux-headers-4.8.11-040811* linux-headers-4.8.11-040811-generic*
  linux-headers-4.8.4-040804* linux-headers-4.8.4-040804-generic*
  linux-headers-4.8.5-040805* linux-headers-4.8.5-040805-generic*
  linux-image-4.7.1-040701-generic* linux-image-4.7.2-040702-generic*
  linux-image-4.7.3-040703-generic* linux-image-4.8.1-040801-generic*
  linux-image-4.8.10-040810-generic* linux-image-4.8.11-040811-generic*
  linux-image-4.8.4-040804-generic* linux-image-4.8.5-040805-generic*
0 upgraded, 0 newly installed, 24 to remove and 2 not upgraded.
After this operation, 2,330 MB disk space will be freed.
Do you want to continue? [Y/n] 

The Code

Copy this code to an executable file named rm-kernels in /usr/local/bin:


# NAME: rm-kernels
# PATH: /usr/local/bin
# DESC: Provide zenity item list of kernels to remove

# DATE: Mar 10, 2017. Modified Jul 28, 2017.

# NOTE: Will not delete current kernel.

#       With 10 kernels on an SSD, empty cache from sudo prompt (#) using:
#       # free && sync && echo 3 > /proc/sys/vm/drop_caches && free
#       First time for `du` 34 seconds.
#       Second time for `du` 1 second.

# PARM: If any parm 1 passed use REAL kernel size, else use estimated size.
#       By default `du` is not used and estimated size is displayed.

# Must be running as sudo
if [[ $(id -u) != 0 ]]; then
    zenity --error --text "root access required. Use: sudo rm-kernels"
    exit 99


current_version=$(uname -r)

for f in /boot/vmlinuz*
    if [[ $f == *"$current_version"* ]]; then continue; fi # skip current version
    [[ $f =~ vmlinuz-(.*) ]]
    v=${BASH_REMATCH[1]}        # example: 4.9.21-040921-generic
    v_main="${v%-*}"            # example: 4.9.21-040921

    # Kernel size in /boot/*4.9.21-040921-generic*
    s=$(du -ch /boot/*-$v* | awk '/total/{print $1}')

    if [[ $# -ne 0 ]] ; then    # Was a parameter passed?
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             # Kernel headers size in /usr/src/*4.9.21-040921*
             s2=$(du -ch --max-depth=1 /usr/src/*-$v_main* | awk '/total/{print $1}')
             s2="0M"            # Linux Headers are not installed
        # Kernel image size in /lib/modules/4.9.21-040921-generic*
        s3=$(du -ch --max-depth=1 /lib/modules/$v* | awk '/total/{print $1}')
        # Estimate sizof of optional headers at 125MB and size of image at 220MB
        if [[ -d "/usr/src/linux-headers-"$v_main ]] ; then
             s2="0M"            # Linux Headers are not installed

    # Strip out "M" provided by human readable option of du and add 3 sizes together
    s=$(( ${s//[^0-9]*} + ${s2//[^0-9]*} + ${s3//[^0-9]*} ))
    t=$(( t + s ))
    s=$s" MB"
    d=$(date --date $(stat -c %y $f) '+%b %d %Y') # Last modified date for display
    choices=("${choices[@]}" false "$v" "$d" "$s")

# adjust width & height below for your screen 640x480 default for 1920x1080 HD screen
# also adjust font="14" below if blue text is too small or too large

choices=(`zenity \
        --title "rm-kernels - Total: $t MB excluding: $current_version" \
        --list \
        --separator="$IFS" \
        --checklist --multiple \
        --text '<span foreground="blue" font="14">Check box next to kernel(s) to remove</span>' \
        --width=640 \
        --height=480 \
        --column "Select" \
        --column "Kernel Version Number" \
        --column "Modified Date" \
        --column " Size " \

for choice in "${choices[@]}" ; do
    if [ "$i" -gt 0 ]; then list="$list- "; fi # append "-" from last loop

    short_choice=$(echo $choice | cut -f1-2 -d"-")
    header_count=$(find /usr/src/linux-headers-$short_choice* -maxdepth 0 -type d | wc -l)

    # If -lowlatency and -generic are purged at same time the _all header directory
    # remains on disk for specific version with no -generic or -lowlatency below.
    if [[ $header_count -lt 3 ]]; then
        # Remove all w.x.y-zzz headers
        list="$list""linux-image-$choice- linux-headers-$short_choice"
        # Remove w.x.y-zzz-flavour header only, ie -generic or -lowlatency
        list="$list""linux-image-$choice- linux-headers-$choice" 


if [ "$i" -gt 0 ] ; then
     apt-get purge $list

NOTE: You need sudo permission to create the file so use:

gksu gedit /usr/local/bin/rm-kernels

To make file executable use:

sudo chmod +x /usr/local/bin/rm-kernels

NOTE: For a server (Text based, not GUI) version of this script see: How do I remove old kernel versions to clean up the boot menu?

July 28, 2017 Updates

The calculated size of each kernel was taken from /boot/*kernel_version* which were 5 files totaling ~50 MB. The formula has changed to include the files in /usr/src/*kernel_version* and /lib/modules/*kernel_version*. The calculated size for each kernel is now ~400 MB. The above code for rm-kernels and rm-kernels-server has been updated. However, the sample screens above do not reflect these changes yet.

The default is to estimate the size of files for linux-headers at 125 MB and linux-image at 220 MB because du can be painfully slow unless files are in cache. To get the real size using du pass any parameter to the script.

The total of all kernel sizes (excluding the current running version which cannot be removed) is now show in the title bar.

The dialog box used to display each Kernel's Last Access Date. This date can get mass overwritten for all kernels during backup or similar operations. The dialog box now shows the Modified Date instead.

  • You are amazing! Really great thanks! You made me happy! – zhartaunik Jun 16 '17 at 16:00

You can easily handle kernels via synaptic package manager. But first you should know a current used kernel-release name, in terminal prompt:

linux@linux-desktop:~$ uname -r 4.4.0-75-generic So at least this version you should keep untouched. Open synaptic and start fill in quick filter placeholder as shown below: enter image description here Now you can select all packages which you wish to delete and do the following: Mark for complete removal -> Apply. I would suggest to keep at least a latest current kernel package and one previous kernel. For instance in this case you can safely get rid of linux-image-4.4.0-66-generic and linux-image-extra-4.4.0-66-generic, but it good to keep 4.4.0-72 and of course 4.4.0-75.


For commandline ease:


git clone https://github.com/erichs/bootnukem.git
cd bootnukem
sudo ./install.sh


sudo bootnukem --dry-run

Works on Linux Mint 18.3 (based on Ubuntu 16.04).

sudo apt-get purge $(dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | head -n -1) --assume-yes

Source: https://ubuntuforums.org/showthread.php?t=2248846&p=13146650#post13146650

protected by Community Jul 30 '14 at 18:46

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.