How to Manage Third-Party APT Repos on Debian with extrepo

Adding third-party repositories on Debian traditionally requires downloading GPG keys, writing DEB822 source files, and keeping track of which repositories you configured manually. Debian’s extrepo tool handles all of this through a single command interface, pulling from a curated list of external repository definitions maintained by the Debian project. Whether you need Docker, VS Code, Brave, Signal, or any of the 200+ repositories in the catalog, extrepo configures the correct source entry, downloads the GPG key, and detects your Debian version automatically. By the end of this guide, you will be able to search, enable, disable, update, and remove third-party repositories on Debian using extrepo, including repositories that fall under non-free licensing policies.

How extrepo Manages Third-Party Repositories on Debian

Manual third-party repository setup on Debian involves several error-prone steps: importing a GPG key to the correct keyrings directory, writing a properly formatted .sources file, and configuring the right suite and components for your Debian release. Mistakes in any of these steps cause APT errors, broken updates, or security warnings. The extrepo tool eliminates this complexity by packaging repository definitions into a Debian-maintained catalog that maps each external repository to its correct URL, GPG key, supported architectures, and compatible Debian versions.

Repository definitions come from the extrepo-data project on Salsa, where Debian maintainers review and curate each entry. This means the GPG keys and repository URLs you get through extrepo have been verified by the Debian project rather than sourced directly from third-party vendors. The table below compares both approaches:

FeatureextrepoManual Configuration
GPG Key ManagementAutomatic (downloaded and stored by extrepo)Manual (download, dearmor, place in keyrings)
Source File FormatDEB822 .sources (auto-generated)DEB822 .sources (hand-written)
Debian Version DetectionAutomatic (configures correct suite)Manual (must specify codename)
Disable/Re-enableSingle command (extrepo disable)Edit or delete file manually
Repository Updatesextrepo update refreshes catalogRequires manual URL/key changes
Debian Support11, 12, 13+All versions
Best ForMost users; quick, reliable setupCustom configs, scripted deployments, air-gapped systems

Install extrepo on Debian

These instructions apply to Debian 13 (Trixie), Debian 12 (Bookworm), and Debian 11 (Bullseye). The extrepo package is available in the default repositories on all three releases. Commands work identically unless noted otherwise.

Update the System

Refresh APT’s package metadata and apply any pending updates before installing new packages:

sudo apt update && sudo apt upgrade

If this is the first time you are using sudo, see add a user to sudoers on Debian to configure your account for administrative access.

Install extrepo and Offline Data

Install the extrepo package along with extrepo-offline-data, which caches the repository catalog locally so searches work without an internet connection on the first run:

sudo apt install extrepo extrepo-offline-data

On Debian 11 (Bullseye), the extrepo-offline-data package is not available. Install extrepo alone and run sudo extrepo update after installation to download the repository catalog.

Verify the installation by checking the installed package version:

dpkg -l extrepo | grep ^ii

Expected output on Debian 13:

ii  extrepo        0.14       all          External repository manager

The version varies by release: Debian 13 ships 0.14, Debian 12 ships 0.11, and Debian 11 ships 0.8. All versions covered in this guide support the same core commands.

Search the extrepo Repository Catalog on Debian

The extrepo search command queries the repository catalog and lists every external repository that matches your search criteria. Running it without arguments shows the complete catalog:

extrepo search

This prints every repository in the catalog with its name, description, and source URL. The list contains over 200 entries on Debian 12 and 13. A condensed sample of the output:

brave_release: Brave Browser (release)
  Components: main
  Suites: stable
  Types: deb
  URIs: https://brave-browser-apt-release.s3.brave.com/

docker-ce: Docker CE
  Components: stable
  Suites: bookworm
  Types: deb
  URIs: https://download.docker.com/linux/debian

signal: Signal
  Components: main
  Suites: xenial
  Types: deb
  URIs: https://updates.signal.org/desktop/apt

vscode: Visual Studio Code
  Components: main
  Suites: stable
  Types: deb deb-src
  URIs: https://packages.microsoft.com/repos/code

Filter extrepo Search with Regex Patterns

Pass a keyword to narrow results. The search key is treated as a regular expression and matches against repository names, descriptions, and URLs. This means you can combine patterns to search for multiple repositories at once:

extrepo search "brave|chrome|edge"

A single-keyword search works the same way:

extrepo search brave
brave_beta: Brave Browser (beta)
  Components: main
  Suites: stable
  Types: deb
  URIs: https://brave-browser-apt-beta.s3.brave.com/

brave_nightly: Brave Browser (nightly)
  Components: main
  Suites: stable
  Types: deb
  URIs: https://brave-browser-apt-nightly.s3.brave.com/

brave_release: Brave Browser (release)
  Components: main
  Suites: stable
  Types: deb
  URIs: https://brave-browser-apt-release.s3.brave.com/

Each result lists the repository name you pass to extrepo enable. In this case, brave_release is the stable channel. For the full Brave setup walkthrough, see install Brave Browser on Debian.

Repository names must match exactly. If extrepo search returns no results for a keyword you expect, browse the full catalog online to find the correct entry name. Select your Debian release to see every available repository. You can also list the local catalog files directly at /usr/share/extrepo/repos.d/.

Enable a Third-Party Repository with extrepo on Debian

After finding a repository, enable it with a single command. This example enables the Jellyfin media server repository:

Some repositories require non-free or contrib policies before extrepo enable will accept them. If the command returns a policy error, configure the required policies first (see Enable Non-Free and Contrib Repositories below).

sudo extrepo enable jellyfin

This creates a DEB822 source file at /etc/apt/sources.list.d/extrepo_jellyfin.sources and downloads the repository’s GPG key to /var/lib/extrepo/keys/jellyfin.asc. Update APT to fetch the new repository’s package list:

sudo apt update

Confirm that packages from the new repository are visible to APT:

apt-cache policy jellyfin-server
jellyfin-server:
  Installed: (none)
  Candidate: x.x.x
  Version table:
     x.x.x 500
        500 https://repo.jellyfin.org/debian [your-release]/main amd64 Packages

The version number and release name are placeholders. Your output will show the actual version and your Debian release codename (for example: bullseye, bookworm, or trixie).

The output confirms that APT can see the Jellyfin packages from the external repository. You can now install with sudo apt install jellyfin. For the full Jellyfin walkthrough, see install Jellyfin Media Server on Debian.

What extrepo Creates on Your System

When you enable a repository, extrepo writes two files. The source configuration goes to /etc/apt/sources.list.d/ and the GPG key goes to /var/lib/extrepo/keys/. Inspect the generated source file to see what extrepo configured:

cat /etc/apt/sources.list.d/extrepo_jellyfin.sources
Types: deb
URIs: https://repo.jellyfin.org/debian
Suites: [your-release]
Components: main
Signed-By: /var/lib/extrepo/keys/jellyfin.asc
Architectures: amd64 arm64 armhf

The Signed-By field points to the GPG key that extrepo downloaded, and the Suites field matches your Debian release codename automatically. This DEB822 format is the same structure you would write by hand when configuring repositories manually.

Disable and Re-enable extrepo Repositories on Debian

Disabling a repository keeps its configuration file in place but tells APT to skip it during updates. This is useful when troubleshooting dependency conflicts or temporarily removing a source without deleting its configuration:

sudo extrepo disable jellyfin

This adds an Enabled: no line to the .sources file. APT ignores the repository until you re-enable it. Verify the change:

cat /etc/apt/sources.list.d/extrepo_jellyfin.sources
Enabled: no
Types: deb
URIs: https://repo.jellyfin.org/debian
Suites: [your-release]
Components: main
Signed-By: /var/lib/extrepo/keys/jellyfin.asc
Architectures: amd64 arm64 armhf

Re-enable the repository by running the same enable command:

sudo extrepo enable jellyfin

This removes the Enabled: no line and restores normal APT access to the repository.

Re-enabling a previously disabled repository restores the existing configuration without refreshing it from the catalog. If the upstream repository changed its URL or rotated its GPG key while the repo was disabled, run sudo extrepo update repo-name after re-enabling to fetch the latest metadata.

Enable Non-Free and Contrib Repositories with extrepo on Debian

By default, extrepo only allows enabling repositories categorized under the main policy. Repositories for proprietary software like Google Chrome, Microsoft Edge, Opera, and Slack are classified under non-free. While extrepo search displays these repositories regardless of your policy setting, attempting to enable one with extrepo enable fails until you add the required policy. This design mirrors Debian’s separation of free and non-free software.

Edit config.yaml to Add Non-Free Policies

The configuration lives at /etc/extrepo/config.yaml. Open it to see the default policy settings:

cat /etc/extrepo/config.yaml
---
url: https://extrepo-team.pages.debian.net/extrepo-data
dist: debian
version: [your-release]
# To enable repositories that host software with non-DFSG-free licenses,
# uncomment "contrib" and/or "non-free" in the list below.
enabled_policies:
- main
# - contrib
# - non-free

The contrib and non-free lines are commented out. Uncomment them with sed to allow enabling repositories under those policies:

sudo sed -i 's/^# - contrib/- contrib/' /etc/extrepo/config.yaml
sudo sed -i 's/^# - non-free/- non-free/' /etc/extrepo/config.yaml

Confirm the change applied correctly:

cat /etc/extrepo/config.yaml
---
url: https://extrepo-team.pages.debian.net/extrepo-data
dist: debian
version: [your-release]
enabled_policies:
- main
- contrib
- non-free

Test Enabling a Non-Free Repository

Test the policy change by enabling a non-free repository. Before the change, this command would fail with a policy error:

sudo extrepo enable google_chrome

If the command completes without output, the policy change worked. Verify the source file was created:

cat /etc/apt/sources.list.d/extrepo_google_chrome.sources
Types: deb
URIs: http://dl.google.com/linux/chrome/deb/
Suites: stable
Components: main
Signed-By: /var/lib/extrepo/keys/google_chrome.asc

If you do not need Chrome, disable it afterward with sudo extrepo disable google_chrome. Repositories like edge, opera_stable, and slack are also now available for enabling. For more on Debian’s non-free component policies, see enable contrib and non-free repos on Debian.

Update the extrepo Catalog on Debian

The repository catalog that extrepo uses can become outdated as upstream maintainers add new repositories or update GPG keys. Refresh the local catalog to get the latest definitions:

sudo extrepo update

This downloads the latest catalog data from the extrepo-data project. Run this before enabling a repository that was recently added to the catalog. If you installed extrepo-offline-data, it provides a baseline catalog through APT updates, but extrepo update fetches the most current version directly.

When run without arguments (Debian 13+), extrepo update rewrites the APT configuration and GPG keyring for every extrepo_* file in /etc/apt/sources.list.d/, including disabled repositories. Disabled repositories remain disabled after the update; only their metadata is refreshed.

On Debian 11 (extrepo 0.8), extrepo update without a repository name argument is not supported and returns an error. On Debian 12 (extrepo 0.11), it may produce a Perl error. The command works reliably without arguments on Debian 13 (extrepo 0.14). If you encounter errors on older releases, specify a repository name: sudo extrepo update repo-name.

Fix Vendor Repository Conflicts with extrepo on Debian

Some vendor packages create their own repository files during installation, which can conflict with the source file that extrepo already configured. Google Chrome is the most common example. When you install Chrome after enabling the google_chrome repository through extrepo, Chrome’s installer writes a legacy .list file to /etc/apt/sources.list.d/ that duplicates the repository entry without the Signed-By field. This causes APT to report a conflict:

E: Conflicting values set for option Signed-By regarding source http://dl.google.com/linux/chrome/deb/ stable: /var/lib/extrepo/keys/google_chrome.asc != 
E: The list of sources could not be read.

Remove Duplicate .list Files from Vendor Installers

Remove the duplicate .list files that the vendor installer created. Each Chrome channel (stable, beta, unstable) may create its own file, so use a glob pattern:

sudo rm -f /etc/apt/sources.list.d/google-chrome*.list
sudo apt update

The .list files do not reappear during Chrome updates because Google’s installer creates them only on the first install. This behavior is controlled by the repo_add_once flag in /etc/default/google-chrome. A full reinstallation of Chrome would recreate the files, requiring you to remove them again.

Microsoft Edge exhibits the same behavior. If you enabled the edge repository through extrepo and see a similar Signed-By conflict, remove the corresponding .list file:

sudo rm -f /etc/apt/sources.list.d/microsoft-edge*.list
sudo apt update

Use extrepo with Tor and Custom Mirrors on Debian

The extrepo tool supports routing repository traffic through Tor and pointing at custom mirrors. These options are useful for privacy-sensitive environments or organizations that maintain internal mirrors of external repositories.

Route extrepo Through Tor

The --tor flag configures how extrepo routes APT traffic through the Tor network. Install the required transport first:

sudo apt install apt-transport-tor

Then enable a repository with Tor routing:

sudo extrepo --tor auto enable signal

The --tor flag accepts five modes:

ModeBehavior
onionUses the .onion URL from the catalog. Fails if none exists for the repository.
tunnelPrepends tor+ to the standard URL, tunneling all traffic through Tor without using .onion addresses.
autoUses .onion if available, otherwise falls back to tunnel mode.
if-onionUses .onion if available, otherwise uses the regular URL without Tor.
offNo Tor routing (default).

To set a default Tor mode that applies to all future extrepo commands, add a tor: line to /etc/extrepo/config.yaml:

tor: auto

Use a Custom Mirror with extrepo

The --mirror flag overrides the repository URL while keeping the original GPG key authentication from the extrepo catalog. This is useful when your organization mirrors external repositories internally:

sudo extrepo --mirror https://mirror.internal.example.com/docker enable docker-ce

The --url flag serves a different purpose: it replaces the extrepo catalog source itself, allowing you to host a private copy of the extrepo-data definitions. To use the offline data package as the catalog source without fetching from the internet:

sudo extrepo --offlinedata search brave

Troubleshoot Common extrepo Issues on Debian

Repository Not Found in Search Results

If extrepo search does not return a repository you expect, the cause is usually either an outdated catalog or a non-free policy requirement. Update the catalog and check your policies:

sudo extrepo update
cat /etc/extrepo/config.yaml

Verify that contrib and non-free are uncommented under enabled_policies if you are trying to enable proprietary software repositories. If the repository still does not appear in search results, it may not yet be included in the extrepo-data catalog. Fall back to manual DEB822 configuration for repositories not in the catalog.

extrepo update Fails Without Arguments

On Debian 11, running sudo extrepo update without specifying a repository name returns an “Update without a repository is not yet supported” error. On Debian 12, it may produce a Perl error. Specify a repository name to work around this:

sudo extrepo update jellyfin

On Debian 13 (extrepo 0.14), sudo extrepo update without arguments works correctly and refreshes all enabled repositories.

GPG Key Errors After Enabling a Repository

If APT reports a GPG signature error after enabling a repository, the key in extrepo‘s catalog may be outdated while the upstream repository has rotated its signing key. Refresh the catalog and re-enable the repository to fetch the updated key:

sudo extrepo update
sudo extrepo disable repo-name
sudo extrepo enable repo-name
sudo apt update

Replace repo-name with the actual repository name. If the error persists, the upstream key rotation may not have been reflected in the catalog yet.

Packages Missing After Enabling a Repository

Some extrepo entries represent repositories that publish multiple packages under different names. If you enabled a repository but cannot find the expected package, search APT directly:

sudo extrepo enable google_chrome
sudo apt update
apt search google-chrome
google-chrome-beta/stable 144.0.7559.31-1 amd64
  The web browser from Google
google-chrome-stable/stable 143.0.7499.169-1 amd64
  The web browser from Google
google-chrome-unstable/stable 145.0.7587.4-1 amd64
  The web browser from Google

A single extrepo entry can provide packages across multiple release channels. Always run apt search after enabling to discover all available packages.

Remove extrepo and Clean Up Repositories on Debian

Disable Individual Repositories

To stop using a specific repository without removing extrepo itself, disable it and then delete the source file and key:

sudo extrepo disable jellyfin
sudo rm -f /etc/apt/sources.list.d/extrepo_jellyfin.sources
sudo rm -f /var/lib/extrepo/keys/jellyfin.asc
sudo apt update

Remove extrepo Completely

Before removing extrepo, disable all repositories it manages. List the active source files to see which repositories are currently enabled:

ls /etc/apt/sources.list.d/extrepo_*.sources 2>/dev/null

Disable and remove each one, then uninstall extrepo and its companion packages:

sudo rm -f /etc/apt/sources.list.d/extrepo_*.sources
sudo apt remove --purge extrepo extrepo-offline-data
sudo apt autoremove
sudo rm -rf /var/lib/extrepo/
sudo apt update

The /var/lib/extrepo/ directory contains downloaded GPG keys. This data cannot be recovered after deletion. Packages already installed from extrepo-managed repositories remain on your system but will no longer receive updates once the repository source is removed. Uninstall them separately if they are no longer needed.

Verify that extrepo is fully removed:

dpkg -l extrepo 2>/dev/null | grep ^ii

No output confirms the package was removed. If a version line still appears, run the removal command again.

Frequently Asked Questions About extrepo on Debian

Does extrepo replace manual repository configuration on Debian?

extrepo handles most common third-party repositories, but it only covers repositories included in the Debian-maintained catalog. Repositories not in the catalog still require manual DEB822 .sources configuration. Use extrepo search to check availability before falling back to manual setup.

Is it safe to use extrepo for third-party repositories?

Repository definitions in extrepo are reviewed and maintained by Debian developers through the extrepo-data project on Salsa. GPG keys and repository URLs come from this curated catalog rather than directly from vendor websites. This adds a layer of verification, though the packages themselves are still built and signed by the third-party vendor.

Why can’t I enable some repositories with extrepo?

extrepo enforces Debian’s free software policies through the enabled_policies setting in /etc/extrepo/config.yaml. Proprietary software repositories like Google Chrome, Microsoft Edge, and Slack are classified under non-free. While extrepo search shows all repositories regardless of policy, extrepo enable refuses to activate non-free repositories until you uncomment the contrib and non-free lines in the config file.

How often should I update the extrepo catalog?

Run sudo extrepo update before enabling a new repository, especially if you recently installed extrepo or have not used it in a while. The extrepo-offline-data package provides a baseline catalog through regular APT updates, but extrepo update fetches the latest version directly from the project.

Further Reading and Resources

  • extrepo-data on Salsa – The curated catalog of external repository definitions maintained by the Debian project. Browse the repository list, check supported architectures, and report issues.
  • extrepo source code on Salsa – The extrepo tool itself, including its command-line interface, configuration handling, and integration with APT.
  • Debian Wiki: SourcesList – The complete reference for APT repository configuration, covering both DEB822 and legacy formats.
  • DEB822 Format Reference – Detailed documentation on the modern .sources file format that extrepo generates.
  • Install Backports on Debian – Configure Debian backports for newer package versions without switching to testing or unstable.
  • Install Flatpak on Debian – An alternative approach to installing third-party software using sandboxed Flatpak packages.
  • extrepo(1p) man page – The official command reference covering all subcommands, options, and configuration file syntax.

Conclusion

You now have a working extrepo setup on Debian for managing third-party repositories through a single command interface. The key techniques covered include searching the repository catalog, enabling and disabling repositories, configuring non-free policies, and resolving vendor installer conflicts. For repositories not yet in the extrepo catalog, fall back to manual DEB822 configuration following the same Signed-By and keyrings conventions that extrepo uses internally.

Leave a Comment

Let us know you are human: