A "command not found" error on Ubuntu almost never means a broken system, it usually just means the tool lives in a package you have not installed yet, and sometimes it means you never ran apt update at all, so this guide walks through both cases, the real difference between bash: command not found and E: Unable to locate package, and what to do when the binary is clearly there but the shell still cannot find it.
You type a command straight from a tutorial, hit Enter, and instead of a result you get bash: htop: command not found or something close to it. The first instinct is usually "the server is broken" or "I installed something wrong". In practice it is almost always simpler: the command lives inside a package that this particular server does not have yet. Here is what Ubuntu actually means by command not found, why people confuse it with the very different Unable to locate package, and how to find the right package fast even when its name does not look anything like the command.
Short version.
command not foundis bash telling you it searched every directory listed in$PATHfor an executable with that exact name and found none. If the tool genuinely exists, it is almost always just not installed yet:sudo apt update, thensudo apt install <package>. The package name does not always match the command name:ifconfigandnetstatlive innet-tools,digandnslookupindnsutils,pipinpython3-pip. If apt itself printsCommand 'X' not found, but can be installed with: sudo apt install X, that is not an error, it is a hint from a separate package calledcommand-not-found, and it does not always guess right. A different message with a similar feel but a different cause isE: Unable to locate package, printed byapt installitself when it does not recognize that package name at all: a typo, a missing repository, or a skippedapt update. If the binary appears to exist and the shell still cannot find it, check$PATHwithecho $PATHandwhich -ainstead of reinstalling anything.
What "command not found" actually means
On a phone, "no such app" and "app not installed" are different concepts. Linux does not work that way: a program is just an executable file sitting in one of a handful of standard directories, and the "command" you type is literally that file's name. When you type htop and press Enter, the shell (the program that reads your input and starts processes for you, usually bash on Ubuntu) walks the directories listed in the $PATH environment variable, in order, looking in each one for a file named htop. It checks every directory, finds nothing, and prints bash: htop: command not found.
See the exact list of directories bash searches:
echo $PATH
What you see: a line like /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games, directories separated by colons. Bash checks them left to right and stops at the first match. It never looks inside subdirectories: if a file sits at /opt/mytool/bin/tool and that path is not in the list, the command tool will not resolve even though the file exists and is executable.
This matters because "command not found" is not "this program does not exist anywhere" and it is not necessarily "something on the server is broken". It literally means "no file with this exact name turned up in any of the directories I checked". There are three distinct causes, and each one needs a different fix:
- the program was never installed - by far the most common case on a brand-new VPS;
- the program is installed but lives outside
$PATH, or the current session does not know about it yet; - a plain typo or the wrong case - on Linux,
Python3andpython3are two different names.
The most common cause on a fresh VPS: the package is not installed
A freshly rented server ships with a minimal set of tools, not everything a tutorial might ask for. A guide tells you to run git clone ..., and git might simply not be there yet - that is normal, not a broken install. Software on Ubuntu is installed through apt, a package manager that locates a ready-built program in a repository, downloads it, and configures it with one command instead of you compiling it from source.
Before it can install anything, though, apt needs an up-to-date idea of what exists and in which version. That local list of repository contents is refreshed with its own command:
sudo apt update
Why this comes before the first install. The list of available packages and versions that apt works from was written to the server once, when the image was built, and by now it may be stale or no longer match what the repositories actually serve. apt update does not install anything by itself, it only refreshes what apt knows is available. What you see: a handful of Get: lines, ending with something like Reading package lists... Done.
Next, install the package you actually need:
sudo apt install htop
sudoruns the command with administrator rights; installing system-wide software without it fails with a permissions error;- apt asks for confirmation (
Y/n) and shows how much disk space the install will use.
What you see: download progress lines, then Setting up htop (...) ..., and the prompt returns cleanly with no errors. At that point the command works - run htop again to confirm.
Here's the whole path on a real server, start to finish - using unzip and ifconfig instead of htop so the demo package is one that's genuinely absent by default:
"Command not found" and "Unable to locate package" are two different messages
Beginners regularly mix up two messages that look similar but come from different places and mean different things. The first is bash's response when you try to run a command. The second is apt's response when you try to install a package. Different problems, different fixes.
Message | Who prints it, and when | What to do |
|---|---|---|
| The bash shell, in response to trying to run | Install the package that provides it: |
| The | Check the name for a typo, run |
The practical difference: if you see command not found, you have not tried to install anything yet, you tried to run a command. The fix is to find the right package and install it. If you see Unable to locate package, you already handed apt install a name it does not recognize, either you mistyped it or it needs a repository that is not in your current list. Often these are the same problem seen from two angles: htop does not run, you try sudo apt install htop but fat-finger the name, and you get the second message instead.
The command name and the package name are not always the same word
If package names always matched command names, this section would not exist. A handful of core utilities carry a package name that does not match the command at all, a leftover from splitting related commands into separate packages so small servers do not drag in things they will never use. Here are the mismatches a newcomer setting up a fresh VPS hits most often:
Command you typed | Package to install | Note |
|---|---|---|
|
| Present on most Ubuntu cloud images already, because cloud-init itself depends on it. Missing most often in containers and heavily stripped builds. |
| | After install the command is usually |
| | Older networking tools. Modern Ubuntu leans on |
| usually already installed | Part of |
| | Manual DNS-query tools, not part of the base install. |
| | Own package name, often preinstalled on images. |
| | Own package name. |
| | Own package name. |
| | Own package name; |
| | Own package name. |
| | One bundle package that pulls in a compiler, |
If a command is not in this table, search apt directly - the search itself often points you at the right name:
apt search <name or part of the name>
It searches descriptions as well as package names, so a word like "ping" or "archive" often surfaces the right package even when you cannot guess the exact spelling.
Ubuntu often suggests the package itself, and that is not an error
If you type a command that is genuinely missing from the server but does exist in the repositories, Ubuntu frequently prints something more useful than a bare command not found:
Command 'htop' not found, but can be installed with:
sudo apt install htop
That is not bash's doing, it comes from a separate package called command-not-found: it intercepts a failed command lookup and checks a database of which package ships which binary. Handy - you can copy the suggested line straight out of the terminal.
The feature has real limits worth knowing up front:
- it needs the
command-not-foundpackage installed; some minimal or container images do not have it, and you get a plainbash: htop: command not foundwith no hint at all; - it only knows about packages in repositories you already have enabled, including
universeandmultiverse, so a package living in a third-party repository (a PPA, a vendor's own repo) you have not added yet will not show up as a suggestion; - for niche tools or genuine typos you sometimes get a
did you meanlist of similarly spelled commands instead of an install hint, the same mechanism handling a slightly different case.
In short: if apt hands you a ready-made install command, copy it and run it. If it only prints command not found with no suggestion, that does not mean the package does not exist, it just means the heuristic missed or the hint package itself is not installed. Search by hand with apt search or check the table above.
apt vs apt-get: is there an actual difference
apt and apt-get are, functionally, two front ends over the same underlying package system. apt-get came first and stays deliberately stable in its output format across versions, which is why it is the go-to inside scripts and Dockerfiles that need predictable behaviour. apt arrived later as a friendlier interface aimed at a human sitting at a terminal: it shows a progress bar, reads more cleanly, and picks saner defaults.
For everyday tasks like refreshing the package list or installing a program, there is no practical difference in outcome, both do the same job. The rule of thumb is simple: typing commands yourself, use apt, it is easier to read. Writing automation, a shell script, or a Dockerfile, use apt-get, its output is more stable to parse and does not shift between releases.
Software outside the default repositories: PPAs and third-party sources
Sometimes the version of a program you need is not in Ubuntu's default repositories at all, a specific database release or a vendor's own repository for their tool, say. For this Ubuntu supports third-party repositories: you add their address to the system, and from then on apt sees their packages right alongside the standard ones.
On Ubuntu, PPAs (Personal Package Archives, a platform for third-party repositories run by individual developers) are the common route:
sudo add-apt-repository ppa:owner-name/repo-name
sudo apt update
- after adding any new repository you need another
apt update, without it apt still does not know the new packages exist and you are back toUnable to locate package; add-apt-repositoryitself comes from a separate package,software-properties-common; on some minimal images you need to install that first:sudo apt install software-properties-common.
Caution matters more than convenience here: adding someone else's repository gives them the ability to ship anything to your server disguised as a package update. Only add repositories whose address you found on the official project site or a vendor you actually recognize, not the first link from a random forum thread.
The binary exists, and the shell still cannot find it
Less common but a regular occurrence: you definitely installed the program, or built it yourself, and Ubuntu still says command not found. This usually comes down to one of three things.
1. Its directory is not in $PATH. A frequent case: something installed via pip install --user, or compiled by hand, lands in ~/.local/bin or /usr/local/bin, and those directories are not always part of the search path for your session. Check it:
echo $PATH
which -a <command name>
Unlike plain which, which -a lists every match it finds, not just the first, which is useful if you suspect two versions are installed and the wrong one is winning.
2. Bash cached an old location, or the session never picked up the change. Bash remembers where a command lives so it does not have to search on every single run. If you installed the program in a brand-new terminal, you are fine, but if you installed it in the same session that still cannot find it, clear the cache:
hash -r
Or just open a fresh SSH session, it re-reads $PATH from scratch either way.
3. A typo, or the wrong case. Boring but real: Linux is case-sensitive, Python3 and python3 are different names, and a stray space or an extra hyphen breaks the match just as thoroughly as the file not existing at all.
A specific edge case: a command works without sudo, but not with sudo. When you run something through
sudo, the shell does not search your normal$PATH, it searches a shorter, separate list of directories set in sudo's own configuration, by design: an administrator should not accidentally execute a program from a directory an ordinary user can edit. Tools installed into~/.local/binviapip install --useralmost never make it onto that shorter list. The fix is either the full path to the file (sudo /home/user/.local/bin/tool) or installing system utilities the standard way, throughapt, rather than into a user's home directory.
Snap: a different way to install a program
Some tutorials hand you a command like this instead of apt install:
sudo snap install <name>
Snap is a parallel packaging system on Ubuntu where every program ships bundled with its own dependencies in an isolated container, instead of pulling them from the shared system. It is not a replacement for apt and not straightforwardly better or worse, just a different route to the same result, with its own tradeoffs (easier access to the latest version of a program, but a bit more disk space and a slower first launch). If a guide gives you a snap install command instead of apt install, that is not a mistake in the instructions, it is a deliberate choice by whoever wrote it, and both paths end with a working program.
Tested on
The logic of resolving a command through $PATH, and the split between command not found and Unable to locate package, does not depend on the Ubuntu release, it is bash and apt behaviour that has held steady for many releases. The specific package names in the table apply to Ubuntu 22.04 and 24.04; for newer releases (including 26.04, if it is already available in the panel) check separately, no major renaming of core utilities is on the horizon, but transitional package names like dnsutils do shift over time.
FAQ
Ubuntu says command not found, what do I do?
First rule out a typo, Linux is case-sensitive. If the spelling checks out, the tool is almost certainly just not installed: run sudo apt update, then sudo apt install <package>, keeping in mind the package name does not always match the command (see the table in this guide). If apt already suggested a fix on the line but can be installed with, just copy and run it.
What does apt install Unable to locate package mean?
This message comes from apt install itself, not from bash: apt could not find a package with that name in any repository it has enabled. Three usual causes: a typo in the package name, a stale repository list (run sudo apt update), or the package sitting in a repository you have not added at all, universe, multiverse, or a third-party PPA.
How do I know which package to install for a missing command?
Check first whether apt already told you, on the line Command 'X' not found, but can be installed with. If there is no hint, try apt search <name>, it searches package descriptions as well as exact names. For frequent utilities like ifconfig, dig, or pip it is usually faster to check a ready-made command-to-package table.
What is the difference between apt and apt-get?
For everyday use, practically none, both install, remove, and update packages the same way. apt is newer, easier to read at a glance (progress bar, cleaner output), and the natural choice when you are typing commands yourself. apt-get is older, and its output format is more stable across versions, which is why it usually stays in scripts and Dockerfiles where predictability matters more than readability.
Why does ifconfig say command not found on Ubuntu 24.04?
ifconfig belongs to the net-tools package, which is not part of a default Ubuntu install anymore, newer tools ip and ss from the iproute2 package took its place in the base image. If you specifically need ifconfig, say an older tutorial calls for it, install the package by hand: sudo apt install net-tools.
Why does python3 say command not found on Ubuntu?
On most official Ubuntu cloud images python3 is already installed, since cloud-init, the system that configures a server on first boot, depends on it. A missing command usually shows up in containers or heavily stripped-down builds instead. The fix is the same either way: sudo apt update, then sudo apt install python3. Worth remembering separately: after installing python3-pip, the command is usually pip3, not bare pip.
Takeaways
command not foundis bash reporting that it could not find an executable with that name in any directory listed in$PATH. It means "no file by this name showed up where I looked", not "this program does not exist".Unable to locate packageis a completely different message, fromapt install: apt does not recognize that package name in its enabled repositories. A typo, a stale list (sudo apt update), or a missing repository.- The package name does not always match the command:
ifconfig/netstatlive innet-tools,dig/nslookupindnsutils,pipinpython3-pip,make/gccinbuild-essential. - Apt's
but can be installed withhint is a real feature of thecommand-not-foundpackage, but it has limits: it does not know about third-party repositories and can be missing entirely on minimal images. aptandapt-getare interchangeable for everyday tasks:aptwhen typing by hand,apt-getinside scripts.- Binary exists but still will not run: check
$PATH(echo $PATH,which -a), clear bash's cache (hash -r), or open a new session, rather than reinstalling the program from scratch.
Next steps
- How to restart networking on Ubuntu and Debian - for when installing net-tools or dnsutils turned up a real networking problem underneath.
- Changing a password on Ubuntu - for when the commands resolve fine but you are locked out of access or permissions.
- Common Linux server problems - the rest of the typical failures on a fresh VPS.
