You typed sudo dnf install ffmpeg and the terminal paused
Then it printed a list of fifty packages. Then it asked Is this ok [y/N/d/D/v/V]. You pressed y. The install finished. You ran ffmpeg and it worked. But you didn't know why DNF pulled in libx265 and gstreamer1-plugins-base. You didn't know that DNF checked multiple repositories to find the best version. You didn't know that if you had pressed d, you could have seen the dependency tree.
Or maybe you ran dnf upgrade and the system rebooted with a new kernel that doesn't play nice with your proprietary drivers. You see a wall of text and you're not sure if you should be worried. DNF is the engine under the hood of Fedora. It decides what gets installed, what gets removed, and how packages talk to each other. Getting comfortable with DNF means you stop guessing and start controlling the system.
What's actually happening
DNF stands for Dandified YUM. It replaced YUM in Fedora 22. The name is a joke, but the tool is serious. DNF doesn't just download files. It builds a dependency graph. When you ask for a package, DNF calculates the entire set of changes required to satisfy that request without breaking existing software. It uses a solver to find a valid transaction.
A transaction is atomic. Either everything in the transaction succeeds, or nothing changes. This protects you from half-installed systems. If the process fails halfway through, DNF rolls back. Your system returns to the state before the command. This is why DNF is safer than manual RPM installation. Manual RPM installation skips dependency checks and transaction safety. DNF enforces consistency.
The metadata comes from repositories. DNF downloads metadata first, then packages. The metadata tells DNF what packages exist, what versions are available, and what dependencies they have. DNF caches metadata locally. By default, DNF uses cached metadata if it is less than forty-eight hours old. This speeds up commands. It also means you might not see a new package immediately after it is released.
Run dnf upgrade --refresh weekly. Stale metadata causes phantom dependency errors.
The fix and how-to
Here's how to check whether a package exists and what it does before you install it.
dnf search keyword # Searches the name and summary fields of all packages in enabled repos
dnf info package-name # Shows version, repo, and dependency list without installing
dnf provides /usr/bin/command # Finds the package that owns a specific file path on the system
Here's how to install a package and handle dependencies.
sudo dnf install package-name # Installs the package and resolves all dependencies automatically
sudo dnf install --refresh package-name # Forces a metadata refresh before resolving dependencies
sudo dnf install --best package-name # Forces the solver to use the highest available version even if it causes a downgrade of other packages
Here's how to update your system. dnf upgrade is the standard command for updating packages within the current Fedora release. dnf system-upgrade is a different command used for crossing major releases, such as Fedora 40 to Fedora 41. They are not interchangeable.
sudo dnf upgrade # Updates all installed packages to the latest version in the current release
sudo dnf upgrade --refresh # Updates packages after refreshing metadata to ensure you get the latest security fixes
sudo dnf upgrade package-name # Updates only the specified package and its dependencies
Here's how to remove packages and clean up orphaned dependencies. autoremove is powerful. It removes packages that were installed as dependencies and are no longer needed. Review the list carefully before confirming.
sudo dnf remove package-name # Removes the package but leaves dependencies that are still required by other packages
sudo dnf autoremove # Removes packages that were installed as dependencies and are no longer needed by any installed package
Here's how to manage repositories and install from disabled sources.
dnf repolist # Shows enabled repositories and package counts
sudo dnf install --enablerepo=repo-id package # Installs from a disabled repo without enabling it permanently
Here's how to use transaction history to recover from mistakes. DNF records every install, update, and remove operation. You can undo almost anything.
dnf history # Displays a list of all past transactions with their IDs and states
sudo dnf history undo transaction-id # Reverses the changes made by a specific transaction to restore the previous state
sudo dnf history redo transaction-id # Reapplies the changes from a transaction that was previously undone
Read the transaction summary. DNF tells you exactly what it will change before it changes it.
Verify it worked
Confirm the package is installed and check the version.
dnf list installed package-name # Confirms the package is installed and shows the version
rpm -q package-name # Uses rpm directly to verify installation status
Check the transaction log if you need to audit changes.
dnf history info transaction-id # Shows detailed information about a specific transaction
Check dnf history before you panic. You can undo almost anything.
Common pitfalls and what the error looks like
DNF will refuse to proceed if it detects a conflict. You might see Error: Transaction test error: package python3-3.12.x conflicts with python3-3.13.y. The conflict is intentional. Read the output before forcing. Forcing a transaction with --skip-broken or --force can leave the system in an inconsistent state.
If you see Error: GPG key is already installed, the repository key has been imported twice. This is harmless but noisy. You can suppress it by checking the repository configuration or importing the key manually with rpm --import.
SELinux denials can appear after installing new services. DNF sets SELinux contexts automatically during installation. If a service fails to start, check the logs. SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux.
Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. DNF will overwrite files in /usr/lib/ on upgrade.
Trust the solver. If DNF says there is a conflict, there is a conflict. Do not force it without understanding the cause.
When to use this vs alternatives
Use dnf upgrade when you want to update packages within the current Fedora release. Use dnf system-upgrade when you are moving from one Fedora release to the next, such as Fedora 40 to Fedora 41. Use dnf install --best when the solver fails due to version conflicts and you want to force the highest available version. Use dnf downgrade when a newer package version broke your workflow and you need to revert to a specific older version. Use dnf history undo when a transaction left the system in an inconsistent state and you need to roll back changes. Use dnf provides when you know the command name but not the package name. Use dnf group install when you need a collection of related packages, such as development tools or a desktop environment. Use dnf module list when you need to see available versions of modular packages like Node.js or Python.
Snapshot the system before the upgrade. Future-you will thank you.