»apt-get dist-upgrade« broken? Try to understand

Ubuntu Version:
Ubuntu 25.04 interrupred releaseupgrade to 25.10

Most (around 980) packages are at the level of 25.10, including the package management apt, dpkg & Co.; However, there are still residues (see below) at the level of 25.04.

Desktop Environment (if applicable):
GNOME

First of all – What I DON’T want:
I am not looking for a solution on how to fix package management. I have already successfully tested a practicable workaround. I am concerned here with understanding.

Question one: (optional)
Why has the package ubuntu-desktop-minimal not already been updated with apt-get upgrade --with-new-pkgs, but would it only be updated with apt-get dist-upgrade? Only new packages are installed and none is removed.

Question two:
Why does apt-get dist-upgrade not install the remaining packages, whereby some must be removed? That’s what this command is for.

How does this situation come about?
I started some weeks ago to be prepared for future questions about interrupted ReleaseUpgrade. I wanted to test this situation.

The following have been carried out:

  • clean install of Ubuntu 25.04
  • ReleaseUpgrade to 25.10 intentionally interrupted
  • Repair using
  • sudo dpkg --configure -a
  • sudo apt-get install - f
  • sudo apt-get upgrade
  • systemctl poweroff -i
  • sudo apt-get upgrade --with-new-pkgs

So far, so good. Now it got weird.

col@row:~$ apt-get --version
apt 3.1.6ubuntu2 (amd64)
Supported modules:
*Ver: Standard .deb
 Pkg:  Debian APT solver interface (Priority -1000)
 Pkg:  Debian APT planner interface (Priority -1000)
*Pkg:  Debian dpkg interface (Priority 30)
 S.L: 'deb' Debian binary tree
 S.L: 'deb-src' Debian source tree
 Idx: EDSP scenario file
 Idx: EIPP scenario file
 Idx: Debian Source Index
 Idx: Debian Package Index
 Idx: Debian Translation Index
 Idx: Debian dpkg status file
 Idx: Debian deb file
 Idx: Debian dsc file
 Idx: Debian control file
col@row:~$ sudo apt-get dist-upgrade
[sudo: authenticate] Password:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
  cpp-14 cpp-14-x86-64-linux-gnu eog gcc-14-base gir1.2-peas-1.0 gnupg-l10n
  libabsl20230802 libclang-cpp18 libclang1-19 libglu1-mesa libhidapi-hidraw0
  libllvm18 libllvm19 libmanette-0.2-0 libopengl0 libpeas-1.0-0 libpeas-common
  libsframe1 libsysmetrics1 libu2f-udev libxatracker2 libxcb-damage0
  linux-headers-6.14.0-15 linux-headers-6.14.0-15-generic
  linux-image-6.14.0-15-generic linux-modules-6.14.0-15-generic
  linux-modules-extra-6.14.0-15-generic linux-tools-6.14.0-15
  linux-tools-6.14.0-15-generic x11-apps x11-session-utils xbitmaps xinit xorg
Use 'sudo apt autoremove' to remove them.
The following NEW packages will be installed:
  glycin-loaders hwctl loupe ubuntu-insights
The following packages have been kept back:
  dirmngr gdm3 gir1.2-adw-1 gir1.2-gdm-1.0 gir1.2-glib-2.0 gir1.2-gtk-4.0 gjs
  gnome-control-center gnome-control-center-data gnome-remote-desktop
  gnome-session-bin gnome-session-common gnome-settings-daemon
  gnome-settings-daemon-common gnome-shell gnome-shell-common gnome-terminal
  gnupg gnupg-utils gpg gpg-agent gpg-wks-client gpgconf gpgsm gpgv
  libadwaita-1-0 libgdm1 libglib2.0-0t64 libglib2.0-bin libgnome-menu-3-0
  libgtk-4-1 libgtk-4-bin libgtkmm-4.0-0 libnautilus-extension4 mutter-common
  mutter-common-bin nautilus nautilus-data ubuntu-session
  yaru-theme-gnome-shell
The following packages will be upgraded:
  ubuntu-desktop-minimal
1 upgraded, 4 newly installed, 0 to remove and 40 not upgraded.
Need to get 0 B/8433 kB of archives.
After this operation, 31.1 MB of additional disk space will be used.
Do you want to continue? [Y/n] n
Abort.
col@row:~$

Ah: Just in case this strange behavior could have something to do with the rust-coreutils, I have also switched to the gnu-coreutils tentatively. But that does not affect the situation.

I also tried to install apt and dpkg after sudo apt-get install - f, but at the end I have »41 not upgraded« (one pkg more).

Ubuntu 25.04 reached End of Life on January 15 2026.
Have you seen EOL Upgrade Info?

2 Likes

I knew that plucky is EOL. As I started some weeks ago, I did not need oldreleseses, because the repo of plucky was still active. I think that has nothing to do with the question.

As you can see apt 3.1.6ubuntu2 of 25.10 is installed and not working as expected.

Surely, worth mentioning in your OP?
My mind reading skills are not what they used to be.

1 Like

I am not clear what it is that you do not understand. I offer quotes from the man pages.

upgrade (apt-get(8))
upgrade is used to install available upgrades of all packages currently installed on the system from the sources configured via sources.list(5). New packages will be installed if required to satisfy dependencies, but existing packages will never be removed. If an upgrade for a package requires the removal of an installed package the upgrade for this package isn’t performed.

Now a quote from the man page of apt-get.

dist-upgrade
dist-upgrade in addition to performing the function of upgrade, also intelligently handles changing dependencies with new versions of packages; apt-get has a “smart” conflict resolution system, and it will attempt to upgrade the most important packages at the expense of less important ones if necessary. The dist-upgrade command may therefore remove some packages.

Regards

The effects of that will vary..

I know I can interrupt a release-upgrade with NO consequences if it’s not started installing any packages; ie. is still just doing downloads, however the effects AFTER [newer] packages have started being installed will alter how I fix the issue.

What occurs at release-upgrade is not just the package upgrade (ie. its more than just change of sources from plucky to questing and then upgrade those packages [using apt full-upgrade etc]), so the fix needed maybe more than you appear to be dealing with, or have considered, and the other steps are release specific (ie. 25.04 to 25.10 may differ to other upgrades; ie. 24.10 to 25.04).

If I make a mistake with a release-upgrade, and it’s already past the point where I recognize I can safely cancel the upgrade; I tend to just let it complete, so they system is in a KNOWN state, then either restore my backups, or depending on what the system is actually running, do a non-destructive re-install of the older release to revert myself back to the older release (depending on packages you’re using; or release changes, this maybe an option I’ll try and avoid too! as you only listed release details).

1 Like

You have created a condition that apt is not designed to handle.

One of apt’s assumptions is that the system began from a logically stable state.

You shattered that assumption by interrupting a release-upgrade. Now you have two partial sets of releases jumbled together. Neither is logically stable or complete. Sometimes the Frankensystem won’t even boot. Apt is not designed to recover a system from that situation. It has no memory of what the last stable system looked like. It doesn’t know your intent. It only knows the versions and dependencies are a mess that it cannot solve.

That looks pretty good for a broken release upgrade. I’ve seen it in the thousands of packages.
As you saw, apt will do what it can within the limits of it’s logic.

2 Likes

Thanks for your help.

As you can see from the reference to the man page for »apt-get (8)«, this quote is actually from the apt man page – a program I didn’t use; apt does not recognise the --with-new-pkgs option because it’s already built into the upgrade command. Yes, that is confusing, which is why I’m sticking with apt-get.

Oh, yes. I noticed that. Hence my surprise. As further tests with various clones of this system revealed, the current version of apt/apt-get ignores the packages marked as »to remove« by the old version. Downgrading to the old version makes it work as usual.

Well, the package manager can’t be all that bad. If it were, you’d only be able to use it on servers protected by a UPS, or on laptops with a fully charged battery. A desktop without a backup in case of a power cut shouldn’t be run with it.

I didn’t want to provide too much information at the start that might distract from the question, but I have also documented the situation; this includes, amongst other things

Some informations of the system after interrupted releaseupgrade and before repairing:

side note
Why always LANG=C? Necessary for international use and not optional.

col@row:~$ LANG=C apt list --installed 2> /dev/null |  grep -v ^Listing | wc -l
1537
col@row:~$ LANG=C apt list --installed 2> /dev/null | grep -v ^Listing | sed 's#\(.*\)\[\(.*\)\]#\2#g;s#\(.*\) to: \(.*\)#\1#g' | sort | uniq -c
     11 installed
      1 installed,auto-removable
    560 installed,automatic
     25 installed,local
    940 installed,upgradable
col@row:~$ LANG=C dpkg -l | sed '1,5d' | awk '{print $1}' | sort | uniq -c
     51 iU
   1469 ii
      9 it
      8 ri
col@row:~$ LANG=C dpkg -l | sed '1,5d' | grep -E "^i.|^ri" | wc -l
1537
col@row:~$

after sudo dpkg --configure -a

col@row:~$ LANG=C apt list --installed 2> /dev/null | grep -v ^Listing | sed 's#\(.*\)\[\(.*\)\]#\2#g;s#\(.*\) to: \(.*\)#\1#g' | sort | uniq -c
     11 installed
    560 installed,automatic
      1 installed,auto-removable
     25 installed,local
    940 installed,upgradable
col@row:~$ LANG=C dpkg -l | sed '1,5d' | awk '{print $1}' | sort | uniq -c
   1527 ii
      2 iU
      8 ri
col@row:~$

after sudo apt-get install -f

col@row:~$ LANG=C apt list --installed 2> /dev/null | grep -v ^Listing | sed 's#\(.*\)\[\(.*\)\]#\2#g;s#\(.*\) to: \(.*\)#\1#g' | sort | uniq -c
     11 installed
    564 installed,automatic
      1 installed,auto-removable
     25 installed,local
    936 installed,upgradable
col@row:~$ LANG=C dpkg -l | sed '1,5d' | awk '{print $1}' | sort | uniq -c
   1529 ii
      8 ri
col@row:~$

after sudo apt-get upgrade and sudo apt-get upgrade --with-new-pkgs
note: the status of the system at time of OP

col@row:~$ LANG=C apt list --installed 2> /dev/null | grep -v ^Listing | sed 's#\(.*\)\[\(.*\)\]#\2#g;s#\(.*\) to: \(.*\)#\1#g' | sort | uniq -c
     34 installed
     12 installed,auto-removable
   1452 installed,automatic
     25 installed,local
     41 installed,upgradable
col@row:~$ LANG=C dpkg -l | sed '1,5d' | awk '{print $1}' | sort | uniq -c
   1556 ii
      8 ri
col@row:~$

To me, it certainly looks as though apt/dpkg knows at all times exactly what is in good working order or broken, and what is outdated or up to date.

I was simply naive enough to believe that the package manager’s behaviour would remain the same regardless of the version. That belief has been shattered and replaced by knowledge.

There’s a bit of hyperbole involved.
The important fact here isn’t that the power was cut. Ubuntu systems handle that every day.
It’s also not important that apt was working. That’s more rare, but apt handles that case well.

The important element here is that power was cut in the midst of a release-upgrade, the rare condition when a system is at its most vulnerable.

Historically, we have not provided support for systems broken in that way, since the actual breakage depends upon exactly what was being installed at the moment of power loss, whether it works, whether it’s important, and whether it’s compatible with it’s dependencies/reverse-dependencies. The results can be unpredictable and we have found them tremendously difficult to diagnose remotely using whatever clues the help-seeker can competently share.

That’s why the support community’s advice for two decades has been to reinstall (one hour) instead of open-ended noodling of broken software and broken dependencies. We try to help the noodlers. Sometimes they get lucky and they system can be repaired. Sometimes they don’t.

I suspect you got lucky. Your test resulted in a resolvable solution using ordinary apt tools. Try again a few times, and you might get a wider variety of results.

You might get a satisfying answer to Question one and Question two. The apt developers are here on Discourse (though rarely in the Support section). Be open to the possibility that you might get an great answer from an expert…that is still unsatisfying.

1 Like

Certainly.


I had already suspected that a release upgrade is, on the whole, a complicated process. When you add the unpredictability of an interruption to the mix, it’s pure chaos.

So far, I’ve only figured out that apt-get works differently than expected. I don’t really understand why that is. But I’ll leave it at that and turn my attention back to more important matters.

Nevertheless, here are my possible answers – based on the problem described at the beginning. They have been tested exclusively for this situation, but could serve as inspiration for similar scenarios.

Solution 1
I think, this is the best way.
1.1. Make a list all packages that were hold back and store this list as a temporary file.

LANG=C apt list ~U 2> /dev/null | grep -v ^Listing | cut -d "/" -f1 > /tmp/packages

1.2. Install all packages listes in this file

xargs -a /tmp/packages sudo apt-get install -y

1.3. Mark all listed packages as »auto«(automatic installed)

xargs -a /tmp/packages sudo apt-mark auto

1.4. Finally mark the metapckages for the desktop environment as »manual« to avoid problems wiht autoremove. (Hint: official flavours have other metapackages!)

sudo apt-mark manual ubuntu-desktop-minimal ubuntu-desktop

status

col@row:~$ LANG=C apt list --installed 2> /dev/null | grep -v ^Listing | sed 's#\(.*\)\[\(.*\)\]#\2#g;s#\(.*\) to: \(.*\)#\1#g' | sort | uniq -c
     35 installed
     27 installed,auto-removable
   1490 installed,automatic
     17 installed,local
col@row:~$ LANG=C dpkg -l | sed '1,5d' | awk '{print $1}' | sort | uniq -c
   1569 ii
      1 rc
col@row:~$

Solution 2
Simulate removing package
dpkg -l | grep ^ri | awk '{print $2}' | xargs apt-get purge -s
IF no necassary package would be removed and THEN ONLY

dpkg -l | grep ^ri | awk '{print $2}' | xargs sudo apt-get purge -y
sudo apt-get upgrade --with-new-pkgs

status

col@row:~$ LANG=C apt list --installed 2> /dev/null | grep -v ^Listing | sed 's#\(.*\)\[\(.*\)\]#\2#g;s#\(.*\) to: \(.*\)#\1#g' | sort | uniq -c
     35 installed
     27 installed,auto-removable
   1490 installed,automatic
     17 installed,local
col@row:~$ LANG=C dpkg -l | sed '1,5d' | awk '{print $1}' | sort | uniq -c
   1569 ii
col@row:~$ diff dpkg-l_1 dpkg-l_2
352d351
< rc  keyboxd                                       2.4.4-2ubuntu23.2                          amd64        GNU privacy guard - public key material service
col@row:~$

Solution 3
I think this in not the best practice. So I do not explain in details.
Downgrade apt, apt-utils and dpkg to the versions from plucky and use sudo apt-get dist-upgrade

status

col@row:~$ LANG=C apt list --installed 2> /dev/null | grep -v ^Listing | sed 's#\(.*\)\[\(.*\)\]#\2#g;s#\(.*\) to: \(.*\)#\1#g' | sort | uniq -c
     35 installed
     27 installed,auto-removable
   1496 installed,automatic
     17 installed,local
col@row:~$ LANG=C dpkg -l | sed '1,5d' | awk '{print $1}' | sort | uniq -c
   1575 ii
      1 rc
col@row:~

The 6 additional packages are from Kernel 6.17.0-19 and some other packages got upgrades too.

Solution 4
restore the system to the point after the interrupted releaseupgrade

sudo apt-get istall -f
reboot
sudo apt-get dist-upgrade

no steps between like apt-get upgrade

Output of all queries identical to solution 1.

Meening: I think solution 4 is better than solution 3, but it need to restore the system to an earlier state. In this case it would be better to restore the system to a stable state and retry the releaseupgrade.


All four solutions lead me to a fully upgraded and functional system. Only the obsolete packages must be removed by e. g. autoremove.

1 Like