Ubuntu – Why does apt-get install a newer dependency than supported by the specified package

aptpackage-management

I have encountered a problem where a package, at a specific version, requires another package, also at a specific version, but Apt-Get selects a newer version of the dependency and then fails.

I have experienced this with Puppet Lab's MCollective and the Nginx Mainline PPAs and likely other packages so my question is about the general approach to Apt-Get dependency resolution but I will use Nginx as my example.

I have a package mirror (built with Aptly) containing the v1.7.5 of the nginx-full package and all its dependencies and also the newer v1.7.6 package and all its dependencies.

If I execute apt-get install nginx-full=1.7.5-1+trusty1 then the install fails with the message:

The following packages have unmet dependencies:
 nginx-full : Depends: nginx-common (= 1.7.5-1+trusty1) but 1.7.6-1+trusty1 is to be installed

However, if I execute apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1 then installation succeeds.

When I have both versions 1.7.5 and 1.7.6 of the nginx-common package on the mirror and the nginx-full package explicitly states it requires 1.7.5 of nginx-common, and nginx-full is the package I've requested, why does apt-get still select the incompatible 1.7.6 version of nginx-common?

Here is the output of dpkg -s nginx-full after installing 1.7.5 showing the exact version dependency constraint:

Version: 1.7.5-1+trusty1
Depends: nginx-common (= 1.7.5-1+trusty1), libc6 (>= 2.14), ...

In this instance, the chain of exact versions required is short so the workaround is easy but there are at least two problems for me:

  1. Other packages have much longer chains of dependencies that are tedious to discover and then append to the apt-get command line.
  2. Until a newer version of a dependency is published to a package mirror it is easy to be unaware of the impending issue.

What I can't comprehend is why the dependency resolution is apparently ignoring the exact version constraint on the specified package. More importantly I'd like to know how I can ask Apt-Get to honour the constraints without having to manually replicate the package metadata onto my apt-get parameters.

Best Answer

What you're experiencing is the problem with apt / apt-get not being as smart as you think it is.

This problem happens when trying to downgrade your package(s) or install an older package version than the version the repositories have as the latest candidate (with regard to your apt priority pinning and other policies regarding repository priorities). When you downgrade your package, you actually have to specify for each individual dependency which version you're downgrading to, or in this case which specific version you actually want to install.

In the case of the nginx packages, where nginx-full and nginx-common depend on each other, you have to explicitly tell apt to install each of the packages of the specified version(s). This is because 1.7.6-1+trusty1 supersedes 1.7.5-1+trusty1 by version number. As a result, you have to specifically say "Only install the package of this specific version" because of the superseded version(s) existing, i.e. apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1

Not relevant to your question, but this also happens when you install from a repository that has a lower apt pinning priority than another version, in which case you have to specify the versions and/or source(s) to install from manually, i.e. sudo apt-get install nginx-full/trusty-proposed nginx-common/trusty-proposed being a prime example of trying to install a package and dependencies from the proposed repository, which has a much lower apt priority than PPAs or the main repositories.

Related Question