For years, adding a third-party repository on Fedora took one command: dnf config-manager --add-repo followed by the URL of a .repo file. Vendor install pages, old blog posts and a lot of provisioning scripts still use it. Since Fedora 41, dnf is dnf5, a rewrite whose config-manager plugin replaced the old flags with subcommands. The old form now stops before it downloads anything, with Unknown argument "--add-repo" for command "config-manager", and the same happens to --set-enabled and --set-disabled.
Below we explain what changed and give you the dnf5 form of each command. It also covers the part that catches people later: dnf5 no longer enables or disables a repository by editing its .repo file, so a repository you remove and add back can come back disabled. We ran every command in October 2026 on Fedora 45 and Fedora 44, both with dnf5 5.4.6, and on Rocky Linux 10.2, which still uses dnf 4 and is where the opposite error shows up.
Why dnf5 rejects --add-repo
dnf 4 was written in Python, and its config-manager plugin took everything as flags: --add-repo, --set-enabled, --save. dnf5 is a C++ rewrite, and its config-manager takes a subcommand first and only then the options for that subcommand. There is no compatibility layer, so dnf5 treats an old flag as an argument it does not know and exits with status 2:
sudo dnf config-manager --add-repo https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
Fedora 45 and Fedora 44 print the same line, and nothing has been written to /etc/yum.repos.d/ at this point:
Unknown argument "--add-repo" for command "config-manager". Add "--help" for more information about the arguments.
On a system set to another language, the message is translated, which is why it’s easy to miss when you search for it. With LANG=es_ES.UTF-8 and the Spanish language pack installed, the command (run without sudo) printed Argumento β--add-repoβ desconocido para la instrucciΓ³n βconfig-managerβ. AΓ±ada "--help" para mΓ‘s informaciΓ³n sobre los argumentos. The fix is the same in every language.

You can see what replaced the flags in the plugin’s own help, which lists subcommands where dnf 4 listed flags:
sudo dnf config-manager --help
On dnf5 5.4.6, seven subcommands cover what the old flags did. enable and disable arrived in dnf5 5.4.1, so Fedora 43, which was still on dnf5 5.2.18 in October 2026, lists only the first five and needs setopt instead:
Commands:
addrepo Add repositories from the specified configuration file or define a new repository using user options
setopt Set configuration and repositories options
unsetopt Unset/remove configuration and repositories options
setvar Set variables
unsetvar Unset/remove variables
enable Enables repositories
disable Disables repositories
Old notes and scripts most often hold one of the dnf 4 commands below. The middle column works on every dnf5 release, and the last one needs dnf5 5.4.1 or newer, which Fedora 44 and 45 have. We ran every dnf5 command in the table on Fedora 45 and the dnf 4 column on Rocky Linux 10.
| dnf 4 (Fedora 40 and older, RHEL, Rocky) | dnf5, any version (Fedora 41 and newer) | dnf5 5.4.1 and newer only |
|---|---|---|
dnf config-manager --add-repo URL | dnf config-manager addrepo --from-repofile=URL | Same |
dnf config-manager --set-enabled REPO | dnf config-manager setopt REPO.enabled=1 | dnf config-manager enable REPO |
dnf config-manager --set-disabled REPO | dnf config-manager setopt REPO.enabled=0 | dnf config-manager disable REPO |
How addrepo adds a repository from a .repo URL
Most vendors publish a ready-made .repo file, and --from-repofile is the direct replacement for --add-repo. It downloads the file, checks that it parses as a repository definition, and only then saves it in /etc/yum.repos.d/. Brave’s repository makes a good example, and the Brave on Fedora guide continues from here to the install itself.
sudo dnf config-manager addrepo --from-repofile=https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
cat /etc/yum.repos.d/brave-browser.repo
dnf saves the file under the vendor’s own name and contents, including the GPG key URL that dnf uses to check every package from the repository.
[brave-browser]
name=Brave Browser
enabled=1
gpgcheck=1
gpgkey=https://brave-browser-rpm-release.s3.brave.com/brave-core.asc
baseurl=https://brave-browser-rpm-release.s3.brave.com/$basearch
Checking before saving is the most useful change from dnf 4. We pointed --from-repofile at a missing file, which failed with a 404, and at an ordinary web page, which failed with Missing section header on line 1. Neither attempt left a file behind in /etc/yum.repos.d/, so a typo in the URL can no longer leave a broken repository that makes every later dnf command fail. Confirm that dnf sees the new repository and where it reads it from:
dnf repo info brave-browser
Read the Config file and Base URL lines first. $basearch has already been expanded for your machine, which tells you the variables in the file resolved:
Repo ID : brave-browser
Name : Brave Browser
Status : enabled
Priority : 99
Cost : 1000
Type : available
Metadata expire : 172800 seconds (last: 2026-10-15 15:26:12)
Skip if unavailable : true
Config file : /etc/yum.repos.d/brave-browser.repo
URLs :
Base URL : https://brave-browser-rpm-release.s3.brave.com/x86_64
OpenPGP :
Keys : https://brave-browser-rpm-release.s3.brave.com/brave-core.asc
Verify repodata : false
Running the same addrepo a second time does not quietly replace the file. It refuses, and tells you which repository IDs the existing file defines.
File "/etc/yum.repos.d/brave-browser.repo" already exists and configures repositories with IDs "brave-browser". Add "--overwrite" to overwrite.
Add --overwrite when you mean to refresh the file from the vendor, for example after they change a mirror or rotate the signing key. Scripts that run more than once need it too, because otherwise the second run exits with status 1.
How to define a repository from a base URL
When a vendor or your own team publishes only a package URL and no .repo file, addrepo can write the file for you from options. The --id option sets the section name and file name, and each --set becomes one line of the file, with enabled=1 added for you. The example below uses a placeholder internal repository, so replace the URLs with yours.
sudo dnf config-manager addrepo --id=example-local --set=name="Example local repo" --set=baseurl=https://repo.example.internal/fedora/\$releasever/\$basearch/ --set=gpgcheck=1 --set=gpgkey=https://repo.example.internal/RPM-GPG-KEY-example
cat /etc/yum.repos.d/example-local.repo
Backslashes stop your shell from expanding $releasever and $basearch, so they reach the file as dnf variables, and dnf fills them in for each Fedora release and architecture.
[example-local]
name=Example local repo
enabled=1
baseurl=https://repo.example.internal/fedora/$releasever/$basearch/
gpgcheck=1
gpgkey=https://repo.example.internal/RPM-GPG-KEY-example
Unlike --from-repofile, this form does not contact the server, because there is nothing to download. Our placeholder host does not exist and the command still succeeded, so run sudo dnf makecache afterwards to find out whether the base URL works. If it returns 404 for your Fedora release, our guide to fixing third-party repo 404 errors on Fedora covers the usual causes. Keep gpgcheck=1 with a real key URL; a repository without signature checks will install whatever the server hands it.
What dnf5 changes when you enable or disable a repository
Enabling and disabling is where people get surprised after the error is fixed. In dnf 4, --set-disabled flipped enabled= inside the repository’s own .repo file. Under dnf5 that file is left alone, and the change is recorded in a separate override file, /etc/dnf/repos.override.d/99-config_manager.repo, which dnf reads after the repository files. Disable the Brave repository and compare the two files.
sudo dnf config-manager disable brave-browser
grep -B2 -A1 "brave-browser" /etc/dnf/repos.override.d/99-config_manager.repo
grep enabled /etc/yum.repos.d/brave-browser.repo
Here the override says enabled=0 while the vendor’s file still says enabled=1, and the override wins. The section above it is a different repository that our test enabled earlier:
[fedora-cisco-openh264-source]
enabled=1
[brave-browser]
enabled=0
Our last grep printed enabled=1. Keeping your choices separate from files that vendor packages and --overwrite replace means a refreshed .repo file no longer re-enables a repository you turned off. On Fedora 43, sudo dnf config-manager setopt brave-browser.enabled=0 writes the same override, since disable isn’t there yet. It also has three consequences worth knowing:
- Hand edits stop working. Changing
enabled=in the.repofile does nothing while an override setsenabledfor that repository. Useenable,disableorsetopt, or remove the override withsudo dnf config-manager unsetopt brave-browser.enabled. - Overrides outlive the repository. We disabled Brave, deleted its
.repofile and added it back withaddrepo. It came back disabled, because the[brave-browser]override was still there. Rununsetoptfor a repository before you delete its file. - Globs match more than you expect.
sudo dnf config-manager enable "fedora-cisco*"enabled the OpenH264 repository and its-debuginfoand-sourcecompanions, which most desktops never need. Name repositories exactly.

dnf repo list --all shows the result of both files together, so check it rather than the .repo file when a repository isn’t behaving the way its file says it should. There is also no removerepo subcommand. To remove a repository, clear its override first, then delete its file from /etc/yum.repos.d/.
Why the dnf5 command fails on Rocky Linux and RHEL
RHEL 10 and its rebuilds still ship dnf 4, so the new syntax fails there in the opposite direction. On Rocky Linux 10.2, --add-repo worked as it always has, printing Adding repo from: and the URL, while addrepo --from-repofile ended a long usage message with this line:
dnf config-manager: error: unrecognized arguments: --from-repofile=https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
dnf 4 on Rocky also disables a repository the old way, by writing enabled=0 into its .repo file, so the override behaviour above applies to dnf5, which on these distributions means Fedora 41 and newer. Both behaviours show up in a short session on the Rocky client.

A script or Ansible role that serves both families has to pick the syntax at run time. Checking which dnf answers is more reliable than checking the distribution name, because Fedora 40 and older also run dnf 4. Save this as add-repo.sh:
#!/bin/bash
REPO_URL="https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo"
if dnf --version 2>/dev/null | grep -q "^dnf5"; then
sudo dnf config-manager addrepo --overwrite --from-repofile="$REPO_URL"
else
sudo dnf config-manager --add-repo "$REPO_URL"
fi
Run it with bash add-repo.sh. It added the repository and exited 0 on Fedora 45, Fedora 44 and Rocky Linux 10.2, and --overwrite keeps a second run from failing on Fedora. On Fedora, dnf5’s first line of --version output starts with dnf5, while dnf 4 prints only a version number, which is what the test relies on.
What it means when config-manager itself is unknown
A different error means the plugin isn’t installed at all. config-manager is part of dnf5-plugins, which the Fedora 45 and Fedora 44 images we tested included. If your system doesn’t have it, you get a different message. We removed it on Fedora 45 to show the message, and dnf5 tells you which package provides the command:
Unknown argument "config-manager" for command "dnf5". Add "--help" for more information about the arguments.
It could be a command provided by a plugin, try: dnf5 install 'dnf5-command(config-manager)'
Install the plugins package and the addrepo commands above work straight away.
sudo dnf install dnf5-plugins
Keep one mental model in mind: dnf5 moved repository management from flags to subcommands, and moved your enable and disable choices out of the repository files and into one override file. With those two changes in mind, the DNF5 cheat sheet for Fedora covers the rest of the dnf5 command set, and our Fedora 44 to 45 upgrade guide walks through the release upgrade itself.