Troubleshooting

add-apt-repository: command not found? Fix it on Ubuntu and Debian

Install the package that provides it: sudo apt install software-properties-common. Debian 13 dropped it, so add repos with a .sources file or extrepo.

Published · Updated ~7 min read
On this page

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.

Ubuntu · Debian 12 and older
sudo apt update
sudo apt install -y software-properties-common

Which error do you see?

MessageCauseFix
bash: add-apt-repository: command not foundsoftware-properties-common is not installed (over SSH the line starts with -bash:)Ubuntu or Debian
sudo: add-apt-repository: command not foundThe same; sudo is not the problem. sudo-rs (Ubuntu 25.10, 26.04) prints sudo: 'add-apt-repository': command not foundUbuntu or Debian
Command 'add-apt-repository' not found, but can be installed with:Ubuntu's command-not-found helper; the next line names the packageUbuntu
/bin/sh: 1: add-apt-repository: not foundA Dockerfile RUN line on an image without the packageDockerfile
Error: Unable to locate package software-properties-commonDebian 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-launchpadlibDebian
ModuleNotFoundError: No module named 'apt_pkg'The system python3 was replacedapt_pkg
apt-key: command not foundDebian 13 and Ubuntu 26.04 no longer ship apt-key; old instructions use itManual method

Ubuntu: install software-properties-common

Ubuntu
sudo apt update
sudo apt install -y software-properties-common

On an Ubuntu system with the command-not-found helper, an interactive shell already tells you this:

Ubuntu · example output
Command 'add-apt-repository' not found, but can be installed with:
sudo apt install software-properties-common

The 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:

Ubuntu
sudo add-apt-repository -y ppa:ondrej/php
sudo apt install -y PACKAGE

sudo 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-common works and gives you the command. It is fine for Debian repositories. For a ppa: line it also needs python3-launchpadlib, which it does not pull in; without it the tool crashes with AttributeError: 'NoneType' object has no attribute 'people'. With it, the next apt update fails anyway, because Launchpad builds PPAs for Ubuntu releases and has no bookworm suite: 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-security entry) and did not return before the release; today it exists only in unstable. apt answers Error: Unable to locate package software-properties-common (apt-get prints E: instead of Error:), no matter how often you run apt 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.

Debian 13 · enable trixie-backports
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 PACKAGE

On 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.

Debian · extrepo
sudo apt install -y extrepo
extrepo search NAME
sudo extrepo enable NAME
sudo apt update

extrepo 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.

Debian · Ubuntu · 1. signing key
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.asc

apt 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.

Debian · Ubuntu · 2. sources file (deb822)
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 update

The older one-line format works too:

Debian · Ubuntu · one-line format
echo "deb [signed-by=/etc/apt/keyrings/NAME.asc] REPO_URL SUITE main" \
  | sudo tee /etc/apt/sources.list.d/NAME.list

On 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:

Ubuntu · manual PPA
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 update

In 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:

Dockerfile · Ubuntu or Debian base
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:

Ubuntu
ls -l /usr/bin/python3

Then reinstall the bindings:

Ubuntu
sudo apt install --reinstall -y python3-apt

Call 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:

Rocky · Alma · RHEL 8 to 10
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo REPO_FILE_URL

The same with dnf 5:

Fedora 41+
sudo dnf config-manager addrepo --from-repofile=REPO_FILE_URL

EPEL, the big extra-packages repository:

Rocky · AlmaLinux
sudo dnf install -y epel-release

Copr is the closest thing to a PPA:

Fedora · Rocky · Alma
sudo dnf copr enable OWNER/PROJECT

Verify

Debian · Ubuntu
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 from

If 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.

Related articles

All troubleshooting