Troubleshooting

E: Unable to locate package — why apt cannot find it and how to fix it

apt cannot find the package: an empty index, a disabled component, a wrong name or release. Fixes for Debian 12/13, Ubuntu 22.04/24.04 and Docker.

Published ~8 min read

E: Unable to locate package <name> means apt searched its local package index and found nothing by that name. Most often the index is empty or out of date: run sudo apt update first, because fresh images and containers often ship without one. If it still fails, the name is wrong for your release, or the package lives in a component or repository you have not enabled.

quick fix
sudo apt update
sudo apt install <package>

# still not found? ask apt what it actually knows
apt-cache policy <package>
apt-cache search --names-only <part-of-the-name>

Did you run apt update?

apt never searches the internet when you type apt install. It searches the index under /var/lib/apt/lists, which only apt update downloads. Docker images delete that index to stay small, and a server image can be weeks old. If the directory holds no Packages files, apt knows no packages at all:

is there an index?
ls /var/lib/apt/lists/ | grep -c Packages     # 0 = no index
sudo apt update     # read the output — errors here are the real problem

Read what apt update prints. A 404, a line saying a repository does not have a Release file, or Temporary failure resolving means the index was not refreshed, and every install that follows fails in the same way. If it stops on a lock instead, a background update is running — see Could not get lock /var/lib/dpkg/lock.

In a Dockerfile, update and install in the same RUN:

Dockerfile
RUN apt-get update \
 && apt-get install -y --no-install-recommends curl ca-certificates \
 && rm -rf /var/lib/apt/lists/*

Docker caches each layer. With apt-get update in its own RUN, a cached, weeks-old index gets reused the next time you add a package, and the install fails with “unable to locate” or a 404. Deleting the lists at the end keeps the image small — which is exactly why any later RUN needs its own update.

Is the package name right for your release?

Package names are case-sensitive, change between releases, and are often not the same as the command you want. Check what exists:

search the index
apt-cache search --names-only nginx     # names containing "nginx"
apt search python3-requests             # names and descriptions
apt-cache policy python3-pip            # "Candidate: (none)" = not installable here

For a release you are not logged into, search packages.debian.org or packages.ubuntu.com and pick the release by codename. Names that regularly trip people up:

  • python — current Debian and Ubuntu have no unversioned Python 2 package. Install python3, and python-is-python3 if you want the python command. More in python: command not found.
  • python3-pip on Ubuntu — the name is right, but the package is in universe (see below). Installing pip leads straight to the next error; pip: command not found covers both.
  • dnsutils — the tools behind dig and nslookup are packaged as bind9-dnsutils. dnsutils survives only as a transitional or virtual name, and on Ubuntu 24.04 the old name sits in universe while the real package is in main. Install the new name.
  • software-properties-common — no longer part of Debian 13. See add-apt-repository: command not found for the replacement.
  • docker — Docker’s engine is docker.io in the Debian and Ubuntu archives, or docker-ce from Docker’s own repository. See docker: command not found.

A specific version in the name only works if your release ships that version. On Debian 12, whose Python is 3.11, asking for 3.12 gives this — the extra lines appear because a name with a dot is also tried as a pattern:

apt install python3.12 on Debian 12
E: Unable to locate package python3.12
E: Couldn't find any package by glob 'python3.12'
E: Couldn't find any package by regex 'python3.12'

When you know the command but not the package, ask apt-file. It searches the file lists of every package, installed or not. On most Ubuntu servers the command-not-found helper also suggests the package when you type a missing command.

which package ships a command?
sudo apt install -y apt-file
sudo apt-file update
apt-file search --regexp 'bin/dig$'     # → bind9-dnsutils: /usr/bin/dig

The usual suspects on a minimal server: curl and wget are their own packages (see curl: command not found and wget: command not found), ifconfig comes from net-tools and ps from procps.

Is the package in a component you have not enabled?

Both archives are split into components. Ubuntu has main, restricted, universe and multiverse; Debian has main, contrib, non-free and, since Debian 12, non-free-firmware. A package in a component your sources do not list does not exist as far as apt is concerned. Many images enable less than a full install: Debian’s cloud images, for example, often list main only. Check what this system has enabled:

enabled components
apt-cache policy | grep -o 'c=[a-z-]*' | sort -u
ls /etc/apt/sources.list /etc/apt/sources.list.d/

There are two file formats, and a fresh image can use either, so look in both places. The newer deb822 format is the default on Ubuntu 24.04, in /etc/apt/sources.list.d/ubuntu.sources, and common on Debian 12 and 13 images, in debian.sources. Components are one line:

deb822 · ubuntu.sources (Ubuntu 24.04)
Types: deb
URIs: http://archive.ubuntu.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

The classic one-line format in /etc/apt/sources.list — Ubuntu 22.04, and many Debian installs — puts the components at the end of each line:

one-line format · sources.list
# Ubuntu 22.04
deb http://archive.ubuntu.com/ubuntu jammy main restricted universe multiverse

# Debian 12
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware

Edit the file you actually have, then run sudo apt update. On Ubuntu, sudo add-apt-repository universe does the same edit for you, if software-properties-common is installed. Keep each release’s own lines: copying Ubuntu lines into Debian, or one release’s codename into another, produces a system that breaks on the next upgrade.

Does the package exist for your architecture?

architecture
dpkg --print-architecture      # amd64 or arm64 on most servers

Packages are built per architecture, and some third-party software ships for amd64 only — on an arm64 server apt then reports it as missing. 32-bit packages on a 64-bit system need the architecture added first: sudo dpkg --add-architecture i386 && sudo apt update, then install name:i386.

Is it a third-party package?

docker-ce, google-chrome-stable, newer Node.js and PHP builds and many vendor tools are not in the Debian or Ubuntu archives at all. apt only knows them after you add the vendor’s repository and signing key, run apt update, and see the repository appear without errors. The safe way to add one is shown in the manual method of add-apt-repository: command not found. If apt update then complains about the new repository with NO_PUBKEY, its signing key is missing or not where the source entry expects it.

Also check that the vendor publishes your release. A repository that has no suite for your codename returns a 404 on apt update, and the package stays “unable to locate” — common for the first months after a new Debian or Ubuntu release.

your codename
. /etc/os-release && echo "$VERSION_CODENAME"     # bookworm, trixie, jammy, noble …

What does “Package x has no installation candidate” mean?

A different message with a different cause: apt does know the name, because another package refers to it, but no enabled source offers anything installable under it. This is the output on Debian 12:

apt install python on Debian 12
Package python is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  python-is-python3 2to3

E: Package 'python' has no installation candidate
  • Obsolete — the name was retired. apt often lists the replacement, as above.
  • Virtual — a name such as mail-transport-agent that several real packages provide. apt prints the providers; install one of them by name.
  • Elsewhere — the package exists in a component or release you have not enabled. Same fix as above.
who provides or replaces it?
apt-cache policy <name>
apt-cache showpkg <name>      # see "Reverse Provides:"

Is your release end-of-life?

When a release leaves support, its packages eventually leave the normal mirrors. Ubuntu’s interim releases move to old-releases.ubuntu.com, and Debian releases are moved to archive.debian.org once they are no longer supported. From then on apt update fails with 404s, the index stays empty, and every install says “unable to locate”. Two dates to know: Ubuntu 20.04’s standard support ended in May 2025 (security fixes continue only through Ubuntu Pro), and Debian 11’s LTS ended in August 2026.

which release is this?
cat /etc/os-release

Pointing your sources at an archive mirror lets you install one more package, but the system still gets no security updates. The real fix is a supported release: upgrade in place one release at a time, or reinstall and restore your data. On a VPS, reinstalling a current template from the panel is usually faster than nursing an end-of-life system along — every VMHeaven KVM plan can be reinstalled from the panel whenever you want a clean box, for example as an Ubuntu VPS on 24.04.

What is the equivalent error on Rocky, Alma and Alpine?

dnf says No match for argument followed by Error: Unable to find a match. The fixes have the same shape: find the right name, then enable the repository that has it. On Rocky and Alma 9 that is usually EPEL:

Rocky · AlmaLinux 9
dnf provides '*/bin/dig'                      # → bind-utils
sudo dnf install -y epel-release              # Extra Packages for Enterprise Linux
sudo dnf config-manager --set-enabled crb     # some EPEL packages need CRB (dnf-plugins-core)
sudo dnf install -y htop

Alpine answers ERROR: unable to select packages with (no such package). Containers start without an index, and a hand-installed Alpine may have the community repository commented out:

Alpine
apk update                         # or use apk add --no-cache, which fetches a fresh index
cat /etc/apk/repositories          # is the community line there, uncommented?
apk search -v 'cmd:dig'            # which package provides a command
apk add bind-tools

Frequently asked

Why does apt say unable to locate package on a fresh Ubuntu install?

Most often because the package index has not been downloaded yet — fresh images and Docker containers ship without one. Run 'sudo apt update' and try again. If it still fails, check the name for your release and make sure the universe component is enabled, since common packages such as python3-pip live there.

How do I find which package provides a command?

On Debian and Ubuntu install apt-file, run 'sudo apt-file update', then 'apt-file search bin/<command>'. On Rocky and Alma use "dnf provides '*/bin/<command>'", and on Alpine "apk search -v 'cmd:<command>'". On most Ubuntu servers, typing the missing command also suggests the package.

What does 'has no installation candidate' mean?

apt knows the name, but no enabled source offers an installable package under it. Usually the name is obsolete (python), virtual with several providers (mail-transport-agent), or only available in a component or release you have not enabled. 'apt-cache policy <name>' and 'apt-cache showpkg <name>' show what replaces or provides it.

How do I enable universe on Ubuntu?

Run 'sudo add-apt-repository universe', then 'sudo apt update'. Without software-properties-common, add universe to the Components: line in /etc/apt/sources.list.d/ubuntu.sources (Ubuntu 24.04) or to the deb lines in /etc/apt/sources.list (Ubuntu 22.04), then run apt update.

Related articles

All troubleshooting