The scenario
You just switched from a proprietary operating system or a different Linux distribution. You need a specific tool, maybe a video editor, a programming language, or a network utility. You open the terminal and type sudo dnf install. It works. A week later, you run sudo dnf update and the system grinds to a halt with a dependency conflict. Or you remove a package and suddenly your desktop environment loses its theme engine. Package management on Fedora is powerful, but it expects you to understand how it tracks metadata, resolves dependencies, and rolls back broken transactions. This article covers the exact commands you need, why they behave the way they do, and how to keep your system stable while you experiment.
Run the commands exactly as written. Read the dependency tree before pressing y. Future-you will thank you.
What DNF actually does
DNF is the default package manager for Fedora. It sits on top of RPM, the underlying package format, but handles the heavy lifting that RPM leaves to the user. When you ask DNF to install something, it does not just download a file and unpack it. It reads the repository metadata, calculates a dependency graph, checks for conflicts, downloads the required packages, and runs a transaction. If any step fails, DNF rolls back the entire change so your system does not end up in a half-configured state.
Think of DNF like a project manager for your filesystem. RPM is the contractor that actually installs the files. DNF tells the contractor what to build, checks the blueprints for clashes, orders the materials, and supervises the work. If the contractor drops a brick, DNF cleans up the mess and restores the original floor plan.
This architecture means you rarely need to manually download .rpm files from a website. You let DNF handle the metadata and dependency resolution. Manual RPM installs bypass the dependency checker and often leave orphaned libraries behind. Stick to DNF for system-wide packages.
DNF caches repository metadata in /var/cache/dnf/. The cache tells DNF what packages exist, what versions are available, and how they relate to each other. When the cache is stale, DNF makes decisions based on outdated information. Always refresh the cache before troubleshooting missing packages or version mismatches.
Trust the package manager. Manual file edits drift, snapshots stay.
Installing packages safely
The basic install command looks simple, but the flags you attach change how DNF handles the transaction. Here is how to check whether a package exists and what it provides before you commit to the installation.
dnf search <keyword>
# WHY: searches package names and descriptions without modifying the system
# WHY: helps you verify the exact package name before running install
# WHY: prevents typos from triggering unexpected dependency chains
Once you confirm the name, run the install command. DNF will print a dependency tree and ask for confirmation. Read the tree. It shows exactly what extra libraries or tools will land on your disk.
sudo dnf install <package-name>
# WHY: downloads the package and all unresolved dependencies
# WHY: runs a transaction test before writing files to disk
# WHY: prompts for confirmation to prevent accidental large downloads
If you are installing a package that requires a third-party repository, DNF will refuse to proceed and print Error: Unable to find a match: <package-name>. The package simply does not exist in the enabled repositories. You must enable the correct repository first. Fedora does not ship proprietary codecs or closed-source drivers in the default repos. You will need to configure external sources before DNF can find them.
When you want to install a package without being prompted for confirmation, add the -y flag. Use this only in scripts or when you are absolutely certain of the dependency tree. Interactive confirmation saves you from downloading fifty megabytes of unused libraries.
Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. DNF will overwrite /usr/lib/ files on the next update and erase your changes.
Verify the installation by checking the package info. Run dnf info <package-name> to confirm the version and repository source.
Removing packages without breaking dependencies
Removing a package is not just deleting files. DNF checks whether other installed packages depend on the target. If they do, DNF offers to remove the dependent packages as well. This is called autoremove. It keeps your system clean but can accidentally strip out desktop components if you are not careful.
Here is how to check what depends on a package before you delete it.
dnf repoquery --requires <package-name>
# WHY: lists packages that explicitly require the target package
# WHY: shows you the impact of removal before the transaction runs
# WHY: prevents accidental deletion of core desktop or network components
Run the remove command with caution. DNF will list every package it plans to delete. Scan the list for anything that looks like a core desktop component or a system service. If you see something unexpected, press n and cancel.
sudo dnf remove <package-name>
# WHY: marks the package for deletion and resolves reverse dependencies
# WHY: runs a transaction test to verify system stability
# WHY: prompts for confirmation before removing files from disk
After a removal, run the autoremove command to clean up orphaned dependencies. These are libraries that were installed automatically but are no longer needed by any active package.
sudo dnf autoremove
# WHY: finds packages that were installed as dependencies but are now unused
# WHY: frees disk space and reduces the attack surface of your system
# WHY: keeps the package database synchronized with actual software needs
Firewall rules and service states do not automatically adjust when you remove packages. Run firewall-cmd --reload after every rule change. Otherwise the runtime config and the persistent config diverge.
Check the journal after removal. Run journalctl -xe to see if any services failed to stop cleanly. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu <unit> muscle-memory style.
Updating the system correctly
Fedora releases a new major version every six months. The package manager handles two distinct types of updates. Routine package updates refresh security patches and bug fixes within the same release. Major version upgrades cross release boundaries and require a different command.
For weekly maintenance, use the refresh flag. It forces DNF to download fresh metadata from the repositories instead of relying on cached copies. Cached metadata can cause DNF to think a package is up to date when a newer version actually exists.
sudo dnf upgrade --refresh
# WHY: downloads fresh repository metadata before checking for updates
# WHY: ensures you get the latest security patches and bug fixes
# WHY: prevents stale cache from hiding available package versions
When you need to move from Fedora 40 to Fedora 42, dnf upgrade will not work. It only updates packages within the current release. You must use the system-upgrade plugin. It downloads all the new packages, verifies the transaction, and reboots into a special upgrade environment.
sudo dnf system-upgrade download --releasever=42
# WHY: downloads all packages required for the major version jump
# WHY: verifies dependencies without modifying the running system
# WHY: prepares a clean transaction for the next boot cycle
sudo dnf system-upgrade reboot
# WHY: reboots into the upgrade environment and applies the transaction
# WHY: rolls back automatically if the upgrade fails during boot
# WHY: isolates the upgrade process from your active desktop session
Never mix dnf upgrade and dnf system-upgrade in the same workflow. They use different transaction paths and conflicting metadata. Run the routine upgrade first. Let the system stabilize. Then run the system-upgrade command when you are ready to cross releases.
Snapshot the system before the upgrade. Future-you will thank you.
Verifying your changes
Package managers leave a complete audit trail. You can query the transaction history to see exactly what changed, when it changed, and whether it succeeded. This is your first stop when something breaks after an update.
dnf history
# WHY: lists all past transactions with IDs, dates, and status
# WHY: lets you identify which update introduced a regression
# WHY: provides the transaction ID needed for rollback operations
If a recent update broke a service, you can roll back the entire transaction. DNF stores the old package versions in the cache until you explicitly clean them.
sudo dnf history undo <transaction-id>
# WHY: reverts the filesystem to the state before the specified transaction
# WHY: restores old package versions and removes newly installed files
# WHY: runs a reverse transaction test to ensure stability
Check the status of a specific package to verify its version and origin.
dnf info <package-name>
# WHY: shows the installed version, repository source, and description
# WHY: confirms whether you are running the latest available release
# WHY: helps you track which repository provided a conflicting package
Run journalctl -xe after major changes. Read the actual error before guessing. Half the time the symptom is gone after a reboot.
Common pitfalls and error messages
DNF will stop you from breaking your system, but it requires you to read the output. The most common error is a dependency conflict. It looks like this:
Error: Transaction test error:
package kernel-6.8.5-200.fc40.x86_64 conflicts with kernel provided by kernel-core-6.8.5-200.fc40.x86_64
This happens when two packages try to own the same file or provide the same virtual capability. DNF refuses to proceed because it cannot guarantee filesystem integrity. Do not force the install. Identify which repository is providing the conflicting package and disable it.
Another frequent issue is the GPG key error. DNF verifies the cryptographic signature of every package before installation. If you see Public key for <package>.rpm is not installed, the repository metadata is missing the signing key. Import the key manually or re-enable the repository to trigger the automatic key import.
sudo dnf makecache
# WHY: rebuilds the repository metadata cache and triggers key verification
# WHY: often resolves missing signature errors without manual intervention
# WHY: forces DNF to re-download repository headers and signing keys
SELinux denials sometimes appear after installing new services. They show up in the journal with a one-line summary. Read those before disabling SELinux. The denial usually points to a missing policy module or a misconfigured file context. Fix the policy. Do not set SELinux to permissive as a workaround.
Fedora's release cadence is six months. The N-2 release goes EOL when N+1 ships. Plan upgrades on that cycle. Staying on an EOL release means no security patches and broken repository mirrors.
Check the transaction history first. Roll back before you guess.
Choosing the right package format
Use DNF when you need system-wide tools, kernel modules, or libraries that other packages depend on. Use Flatpak when you want sandboxed desktop applications that update independently of the OS. Use RPM directly only when you are building packages from source or debugging a broken DNF transaction. Stay on the default Fedora repositories for core system stability. Add third-party repositories only when you need proprietary drivers or codecs that Fedora cannot ship legally.
Run journalctl first. Read the actual error before guessing.