apt "E: Unable to locate package": update, enable the component, or find its real name
Fix apt "E: Unable to locate package": run apt update, enable universe or contrib, find the right package name, add the vendor's repository, and handle Docker images.
by OhSudo ·
Checked on real software: Ubuntu 24.04, apt · November 2026How we check
$ sudo apt install htopReading package lists... DoneBuilding dependency tree... DoneReading state information... DoneE: Unable to locate package htopapt doesn’t search the internet when you install something. It looks in a list stored on your machine, built from the repositories you’ve configured. This message means the name isn’t in that list. The list may be empty or old, the repository holding it may not be turned on, or the name may be different.
TL;DR
sudo apt updatesudo apt install htopapt search htop # the right name?apt policy htop # which repository has it?In a Dockerfile, run them in one line: apt-get update && apt-get install -y htop.
1. Update the list
This solves most cases, particularly on a fresh server or container, where the list is empty:
sudo apt updateRead its output, since an error here is the actual problem:
apt update says |
Go to |
|---|---|
Temporary failure resolving 'archive.ubuntu.com' |
Name resolution |
NO_PUBKEY |
GPG error: NO_PUBKEY |
does not have a Release file |
Section 4 |
Could not get lock |
Could not get lock |
2. Is the name right?
Names on Debian and Ubuntu often differ from what you’d expect, and they’re case-sensitive:
apt search '^nginx'apt-cache search postgresql | grep clientapt list 'python3-req*'Some common differences:
| You want | Package |
|---|---|
| Apache | apache2 |
pip |
python3-pip |
| Node.js | nodejs (npm is separate) |
ifconfig, netstat |
net-tools |
dig, nslookup |
dnsutils |
ss, ip |
iproute2 |
ping |
iputils-ping |
Compiler and make |
build-essential |
| A Python library | python3-<name> |
Know the command, and not the package? apt-file finds it:
sudo apt install apt-filesudo apt-file updateapt-file search bin/digDon’t use a version number if the package doesn’t have it. python3.11 exists only on some releases.
3. Enable the component (Ubuntu and Debian)
Repositories are divided into parts, and not all are on by default.
On Ubuntu, universe holds many community packages. Minimal images and cloud images may have it off:
sudo add-apt-repository universesudo apt updateadd-apt-repository comes from software-properties-common, if it isn’t installed.
On Debian, non-free drivers and tools live in contrib, non-free and non-free-firmware. Add them to the lines in /etc/apt/sources.list:
deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmwareSee what’s currently enabled:
grep -rh '^deb\|^Types\|^Components' /etc/apt/sources.list /etc/apt/sources.list.d/Newer systems also use .sources files in that folder, with a Components: line.
4. It isn’t in your release
Packages come and go between releases. Check which release you have, and what it offers:
lsb_release -aapt policy some-packageLook it up on packages.ubuntu.com or packages.debian.org, which also show which release has which version.
Many tools aren’t in the distribution at all, and come from the vendor’s own repository, such as Docker, Terraform, Kubernetes, or a current PostgreSQL. Follow their instructions, which add a key and a source file. A wrong key gives NO_PUBKEY.
A release that’s out of support has moved to another server, so apt update fails with does not have a Release file or 404s. For Ubuntu, it moved to old-releases.ubuntu.com, and for Debian to archive.debian.org. The real fix is upgrading, because nothing there gets security updates.
A PPA on the wrong release gives the same message. Remove it with sudo add-apt-repository --remove ppa:name/here.
5. Architecture
A package for amd64 isn’t found on arm64, such as on a Raspberry Pi or an AWS Graviton instance. Check it:
dpkg --print-architectureapt-cache policy some-packageA vendor’s source line can be limited, as in deb [arch=amd64] ..., which hides it from other architectures.
6. In a Dockerfile
Official images ship without the list, to stay small. So it’s always empty at the start, and you need the update in the same RUN:
RUN apt-get update && apt-get install -y --no-install-recommends curl \ && rm -rf /var/lib/apt/lists/*Keeping update on a separate line gets it cached, and a later build then uses an old list, so packages can’t be found or downloaded. apt also warns about being used in scripts, so use apt-get here.
Your base image might not be Debian-based at all. If apt-get itself isn’t found, you’re probably on Alpine (apk add) or RHEL (dnf install).
Warning
Don’t download a .deb from a random site to get around this, or add a repository from a forum post. Packages run as root when installed, so you’re trusting whoever made them with your whole machine. Mixing repositories from another release can also break your system on the next upgrade.
Shell, we have a problem!
Similar, but different: E: Package 'x' has no installation candidate means the name is known, but nothing can be installed, often because it was replaced. E: Couldn't find any package by glob is the same error with * in the name. dnf reports this as No match for argument, and an old CentOS that can’t reach its mirrors at all says Cannot find a valid baseurl. And Python’s externally-managed-environment is about pip. The following packages have been kept back means apt found the update and chose to wait.
Found this useful? Share it.
Found a mistake? Let us know at contact@ohsudo.com.