Short answer: add-apt-repository: command not found means the helper is not installed. It is not part of apt but a small Python tool from the software-properties-common package, which minimal Ubuntu and Debian installs and Docker images leave out. On Ubuntu, install that package (below). On Debian 13 the package does not exist, so add the repository by hand with a .sources file, or with extrepo; both are shown further down.
sudo apt update
sudo apt install -y software-properties-commonWhich error do you see?
| Message | Cause | Fix |
|---|---|---|
bash: add-apt-repository: command not found | software-properties-common is not installed (over SSH the line starts with -bash:) | Ubuntu or Debian |
sudo: add-apt-repository: command not found | The same; sudo is not the problem. sudo-rs (Ubuntu 25.10, 26.04) prints sudo: 'add-apt-repository': command not found | Ubuntu or Debian |
Command 'add-apt-repository' not found, but can be installed with: | Ubuntu's command-not-found helper; the next line names the package | Ubuntu |
/bin/sh: 1: add-apt-repository: not found | A Dockerfile RUN line on an image without the package | Dockerfile |
Error: Unable to locate package software-properties-common | Debian 13, where the package is gone, or an empty package index. apt-get, and apt on Debian 12 or Ubuntu 24.04, print E: instead of Error: | Debian |
AttributeError: 'NoneType' object has no attribute 'people' | A ppa: line on Debian 12 without python3-launchpadlib | Debian |
ModuleNotFoundError: No module named 'apt_pkg' | The system python3 was replaced | apt_pkg |
apt-key: command not found | Debian 13 and Ubuntu 26.04 no longer ship apt-key; old instructions use it | Manual method |
Ubuntu: install software-properties-common
sudo apt update
sudo apt install -y software-properties-commonOn an Ubuntu system with the command-not-found helper, an interactive shell already tells you this:
Command 'add-apt-repository' not found, but can be installed with:
sudo apt install software-properties-commonThe command is available immediately: no reboot, no new shell. It is also installed as apt-add-repository; both names run the same tool. A typical PPA addition then looks like this. add-apt-repository refreshes the package index by itself unless you pass -n:
sudo add-apt-repository -y ppa:ondrej/php
sudo apt install -y PACKAGEsudo add-apt-repository -L lists the configured repositories (a lowercase -l means “log in to Launchpad” and waits for credentials), and -r removes one again. Logged in as root in a container? Drop the sudo. If sudo itself is missing, see sudo: command not found.
Debian: it depends on the release
- Debian 12 and older:
sudo apt install software-properties-commonworks and gives you the command. It is fine for Debian repositories. For appa:line it also needspython3-launchpadlib, which it does not pull in; without it the tool crashes withAttributeError: 'NoneType' object has no attribute 'people'. With it, the nextapt updatefails anyway, because Launchpad builds PPAs for Ubuntu releases and has nobookwormsuite: the repository “does not have a Release file”. - Debian 13 (trixie): the package is gone. It was removed from Debian testing on 23 October 2024 because of a release-critical bug (Debian bug #1038747: its settings dialog could overwrite the
debian-securityentry) and did not return before the release; today it exists only in unstable. apt answersError: Unable to locate package software-properties-common(apt-get printsE:instead ofError:), no matter how often you runapt update. Use the manual method or extrepo.
For the most common Debian case, backports, you need no helper and no extra key: the suite is signed with the Debian archive key your system already has.
sudo tee /etc/apt/sources.list.d/backports.sources >/dev/null <<'EOF'
Types: deb
URIs: http://deb.debian.org/debian
Suites: trixie-backports
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
EOF
sudo apt update
sudo apt install -t trixie-backports PACKAGEOn Debian 12, write bookworm-backports instead. For third-party software, extrepo is Debian’s own tool: it adds curated external repositories together with their signing keys, so you do not paste a key from a web page.
sudo apt install -y extrepo
extrepo search NAME
sudo extrepo enable NAME
sudo apt updateextrepo enable writes /etc/apt/sources.list.d/extrepo_NAME.sources and stores the key under /var/lib/extrepo/keys/. By default it only offers repositories with DFSG-free software; for others, uncomment contrib or non-free under enabled_policies in /etc/extrepo/config.yaml.
Add a repository without add-apt-repository
All the helper really does is store a signing key and write a sources file. Doing that by hand works on every Debian and Ubuntu release, Debian 13 included. It is also the better choice in Dockerfiles, because software-properties-common pulls in a Python stack. Take the key URL, repository URL and suite from the vendor’s install instructions.
sudo install -d -m 0755 /etc/apt/keyrings
sudo curl -fsSL KEY_URL -o /etc/apt/keyrings/NAME.asc
sudo chmod a+r /etc/apt/keyrings/NAME.ascapt reads an ASCII-armored key directly when the file name ends in .asc, so you do not need gpg, which slim images lack. If the vendor’s key file does not start with -----BEGIN PGP PUBLIC KEY BLOCK-----, it is binary: save it as NAME.gpg and point Signed-By at that file instead. No curl either? The curl: command not found fix comes first.
sudo tee /etc/apt/sources.list.d/NAME.sources >/dev/null <<'EOF'
Types: deb
URIs: REPO_URL
Suites: SUITE
Components: main
Signed-By: /etc/apt/keyrings/NAME.asc
EOF
sudo apt updateThe older one-line format works too:
echo "deb [signed-by=/etc/apt/keyrings/NAME.asc] REPO_URL SUITE main" \
| sudo tee /etc/apt/sources.list.d/NAME.listOn Debian 13, sudo apt modernize-sources converts existing .list files to the .sources format. Docker’s repository is a worked example of this whole pattern in installing Docker on Ubuntu and Debian. If apt update then reports NO_PUBKEY, see GPG error: NO_PUBKEY.
Do not use apt-key add, even if old instructions tell you to. It trusts the key for every repository on the system, it has been deprecated for years, and Debian 13 and Ubuntu 26.04 no longer ship it, hence apt-key: command not found. signed-by limits the key to one repository.
A PPA by hand (Ubuntu only)
This is useful in an Ubuntu container where you do not want software-properties-common. Copy the signing key fingerprint from the PPA’s Launchpad page; the key server returns it as an armored .asc key:
FPR=FINGERPRINT
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x$FPR" \
| sudo tee /etc/apt/keyrings/ondrej-php.asc >/dev/null
sudo tee /etc/apt/sources.list.d/ondrej-php.sources >/dev/null <<EOF
Types: deb
URIs: https://ppa.launchpadcontent.net/ondrej/php/ubuntu
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: main
Signed-By: /etc/apt/keyrings/ondrej-php.asc
EOF
sudo apt updateIn a Dockerfile
ubuntu and debian images ship neither the helper nor gpg, so a RUN add-apt-repository … line stops with /bin/sh: 1: add-apt-repository: not found. Write the two files instead, in the same layer as the install:
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl \
&& install -d -m 0755 /etc/apt/keyrings \
&& curl -fsSL KEY_URL -o /etc/apt/keyrings/NAME.asc \
&& printf 'Types: deb\nURIs: REPO_URL\nSuites: SUITE\nComponents: main\nSigned-By: /etc/apt/keyrings/NAME.asc\n' \
> /etc/apt/sources.list.d/NAME.sources \
&& apt-get update \
&& apt-get install -y --no-install-recommends PACKAGE \
&& rm -rf /var/lib/apt/lists/*If you prefer the helper on an Ubuntu base, install it in the same RUN line with apt-get install -y software-properties-common and call add-apt-repository -y; there is no sudo in the container.
Installed, but it crashes with apt_pkg
If the command exists but fails with ModuleNotFoundError: No module named 'apt_pkg', the system Python was swapped out. add-apt-repository runs on /usr/bin/python3 and needs the distribution’s own version, which is the only one that has the python3-apt bindings. This usually happens after someone pointed python3 at a newer interpreter with update-alternatives.
Check where python3 points; it should be the distribution’s own python3.x:
ls -l /usr/bin/python3Then reinstall the bindings:
sudo apt install --reinstall -y python3-aptCall additional Python versions by their full name (python3.13, for example) instead of replacing the system python3. Parts of Ubuntu depend on it, and python: command not found has the clean way to get a python command.
The RHEL, Rocky, Alma and Fedora equivalent
There is no add-apt-repository on dnf-based systems. To add a .repo file from a URL with dnf 4, as on EL 8, 9 and 10:
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo REPO_FILE_URLThe same with dnf 5:
sudo dnf config-manager addrepo --from-repofile=REPO_FILE_URLEPEL, the big extra-packages repository:
sudo dnf install -y epel-releaseCopr is the closest thing to a PPA:
sudo dnf copr enable OWNER/PROJECTVerify
command -v add-apt-repository # /usr/bin/add-apt-repository
sudo apt update # the new repository appears in the Get:/Hit: lines
apt policy PACKAGE # shows which repository a package comes fromIf apt policy lists the new repository URL under the candidate version, the next apt install takes the package from there. If apt stops with a lock error because a background update is running, see Could not get lock /var/lib/dpkg/lock. If it still cannot find the package, see E: Unable to locate package.
Setting up a new server for this? On an Ubuntu VPS the Ubuntu steps above work as written; on a Debian VPS with Debian 13, use the manual method or extrepo.
Another tool missing, or a directory to add to PATH for good in bash, zsh and fish? See command not found: the three causes and the fix for every tool.
Frequently asked
Which package provides add-apt-repository?
software-properties-common. On Ubuntu, and on Debian 12 or older, 'sudo apt update && sudo apt install -y software-properties-common' makes add-apt-repository (and its alias apt-add-repository) available immediately. Debian 13 does not have the package.
How do I fix add-apt-repository: command not found on Debian 13?
software-properties-common was removed from Debian testing in October 2024 over a release-critical bug and is not part of Debian 13. Add the repository by hand: the key in /etc/apt/keyrings and a .sources file in /etc/apt/sources.list.d. For curated third-party repositories, use extrepo.
Why does sudo say add-apt-repository: command not found?
sudo is not the cause. The command is not installed, and sudo reports that it cannot find it. Install software-properties-common on Ubuntu; on Debian 13 add the repository by hand. Ubuntu 25.10 and 26.04 use sudo-rs, which prints sudo: 'add-apt-repository': command not found.