DNF Package Manager Explained

A Complete Beginner's Guide

DNF is Fedora's default package manager, used to install, update, search, and remove software from official repositories with automatic dependency resolution.

You run sudo dnf install and the terminal spits out a dependency error

You need a tool, but you only know the command name, not the package. Or you upgraded a package and now a service won't start. You have been using Fedora for six months. You know how to install packages. You know sudo asks for your password. Now you need to manage the system with confidence. You need to search effectively, handle updates safely, and recover from mistakes. This article covers the DNF commands you use daily, the flags that prevent data loss, and the mechanics that keep your system consistent.

What DNF actually does

DNF stands for Dandified YUM. It is the package manager for Fedora. It talks to repositories, resolves dependencies, and installs RPM files. Think of DNF as a supply chain manager for your system. You ask for a product. DNF checks the catalog, finds the product, checks what other parts that product needs, ensures none of those parts conflict with what you already have, and then downloads and installs everything in the right order.

If a dependency is missing, DNF stops. It does not install a broken state. This safety is why DNF sometimes seems slow. It is calculating the transaction graph before touching your disk. The calculation ensures that installing package A does not break package B by removing a shared library. DNF guarantees atomic transactions. Either everything installs, or nothing changes. Your system never ends up in a half-updated state.

Finding packages

Start with searching. You rarely need to guess the exact package name. DNF searches names and descriptions across all enabled repositories.

dnf search neovim
# Searches name and description fields across all enabled repos
# Output includes the package name and a short summary line

When you need a specific binary but do not know the package, use provides. This command maps files and virtual capabilities back to the package that owns them.

dnf provides /usr/bin/vim
# Finds which package owns a specific file path on the system
# Useful when you need a binary but don't know the package name
dnf provides 'python3(requests)'
# Finds the package that provides a Python module import
# The syntax matches the virtual capability used by Python packages

Check details before installing. The info command shows the version, repository, and size.

dnf info htop
# Shows metadata for the package including version, license, and repo
# Displays the list of dependencies the package requires

Run dnf provides when you are stuck. It saves you from guessing package names and reading documentation.

Installing and updating

Install packages with install. DNF resolves dependencies automatically. You do not need to track down prerequisites by hand.

sudo dnf install firefox
# Downloads the package and all unresolved dependencies
# Prompts for confirmation before modifying the system state

Update the system with upgrade. This command updates all installed packages to the latest available versions. It handles kernel updates and dependency shifts safely.

sudo dnf upgrade
# Updates all installed packages to the latest available versions
# Resolves dependencies and handles kernel updates automatically

Run dnf upgrade --refresh for weekly maintenance. This forces DNF to check the repo metadata again. Repositories cache metadata to save bandwidth. The --refresh flag clears that cache and fetches fresh data. Use dnf system-upgrade only when crossing major releases like Fedora 40 to 42. Those are different commands with different risk profiles. dnf upgrade stays within the current release. dnf system-upgrade downloads a new release and reboots into a transactional upgrade. Do not conflate them.

Managing modules

Modules allow Fedora to ship multiple versions of a stack, like Node.js or Python, without breaking dependencies. The persona often misses this feature. Modules lock the system to a specific stream until you change it manually.

List available streams and profiles.

dnf module list nodejs
# Shows available streams and profiles for the nodejs module
# Streams represent major versions like 18 or 20

Install a specific stream. The profile selects which sub-packages get installed.

sudo dnf module install nodejs:20/common
# Installs the nodejs module stream 20 with the common profile
# Locks the system to this stream until you reset or switch

Modules lock the dependency stream. If you install nodejs:20, DNF will not upgrade nodejs to version 21 automatically. You must switch streams manually. This prevents accidental version jumps in development environments. Run dnf module reset nodejs to unlock the stream before switching.

Check dnf module list when a package version seems stuck. The module lock is usually the cause.

Transaction history and recovery

DNF keeps a full log of every install, update, and removal. This history is your safety net.

dnf history
# Lists all past transactions with ID, command, and date
# Each line has a unique ID number for undo or redo operations

View details of a specific transaction.

dnf history info 5
# Shows the exact packages added, removed, and updated in transaction 5
# Includes the command line that triggered the transaction

Undo a transaction if it broke something.

sudo dnf history undo 5
# Reverses the changes made in transaction ID 5
# Restores removed packages and reinstalls downgraded ones

Check dnf history before you panic. You can almost always undo the last change. The undo operation is atomic and safe.

Repositories and configuration

List enabled repositories to see where packages come from.

dnf repolist
# Shows all enabled repositories with package counts
# Helps you verify that third-party repos like RPM Fusion are active

Manage repositories permanently with config-manager.

sudo dnf config-manager --set-enabled rpmfusion-free
# Enables the rpmfusion-free repository in the configuration
# Changes persist across reboots and future transactions
sudo dnf config-manager --set-disabled rpmfusion-free
# Disables the repository without removing the configuration file
# Useful for troubleshooting or restricting package sources

Temporarily disable a repo for a single command.

sudo dnf install --disablerepo=updates-testing htop
# Runs the install without checking the updates-testing repo
# Useful when a package in testing conflicts with your needs

Config files live in /etc/. Packages ship files to /usr/lib/. Edit /etc/. Never edit /usr/lib/. Changes in /usr/lib/ get overwritten on the next update. DNF respects this separation. If you modify a file in /usr/lib/, DNF will warn you or replace it during an upgrade. Keep your customizations in /etc/ or use a drop-in configuration directory.

Common pitfalls and errors

You will encounter errors. DNF reports them clearly. Read the error before forcing anything.

GPG Key Errors

You will see Public key for package.rpm is not installed when adding a new repository. Fedora requires signed packages. The error means DNF found the package but cannot verify the signature. Import the key or check the repo configuration. Do not disable GPG checking. That opens the door to supply chain attacks.

Public key for htop-3.3.0-1.fc40.x86_64.rpm is not installed
Failing package is: htop-3.3.0-1.fc40.x86_64
GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-40-x86_64

Conflicts

The dnf upgrade command will refuse to proceed and print Error: Transaction test error: package python3-3.12.x conflicts with python3-3.13.y. The conflict is intentional. Read the next paragraph before forcing. DNF detects that two packages cannot coexist. Forcing the install breaks the system. Use dnf swap to replace one with the other, or remove the conflicting package first.

Error: Transaction test error:
  package python3-3.13.1-1.fc41.x86_64 conflicts with python3 provided by python3-3.12.7-1.fc41.x86_64

Swap packages

Use swap to replace packages safely. This is better than removing and installing separately.

sudo dnf swap firefox chromium
# Removes firefox and installs chromium in a single transaction
# Handles dependency resolution for both removal and installation

Cache issues

If you see Failed to download metadata for repo 'updates', your network might be blocking the mirror, or the mirror is down. Run dnf clean all to clear corrupted cache files. Then run dnf upgrade --refresh.

Run journalctl -xe reads better than journalctl alone. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu <unit> muscle-memory style. Check the logs if a service fails after a package update. The logs often show the exact configuration file or dependency that caused the failure.

When to use DNF commands

Use dnf install when you need a package and its dependencies from a repository. Use rpm -i only when you have a standalone RPM file and you accept the risk of manual dependency management. Use dnf download when you need the RPM file for offline installation or inspection. Use dnf module list when you are working with modular stacks like Node.js or Python versions. Use dnf swap when you need to replace one package with another that provides the same functionality. Use dnf autoremove when you want to clean up dependencies that are no longer required by any installed package. Use dnf config-manager when you need to enable or disable repositories permanently. Use dnf history undo when a transaction broke your system and you need to roll back.

Run dnf upgrade --refresh every week. Stale metadata causes phantom errors. Trust the package manager. Manual file edits drift, snapshots stay.

Where to go next