You downloaded a custom kernel module, a proprietary driver, or a tool that the Fedora repositories do not carry. You have the .rpm file sitting in your Downloads folder. You need it installed without breaking the rest of the system. The wrong command here can leave your package manager confused, your services stuck, or your SELinux policy screaming denials.
What is actually happening
An RPM file is a compressed archive with metadata. It contains the files to install and a list of required dependencies. The rpm command installs the archive exactly as described. It does not look for missing dependencies. If a library is missing, rpm stops and fails. It does not fetch the library.
dnf is the transactional package manager. It reads the RPM metadata, checks the configured repositories for missing dependencies, downloads them, and installs everything in one atomic transaction. If the transaction fails, dnf rolls back. The system stays consistent.
Think of rpm as a contractor who installs a window but expects you to have already built the frame and mixed the concrete. Think of dnf as the general contractor who checks the blueprint, orders the concrete, builds the frame, and installs the window. If the concrete delivery is late, the general contractor cancels the job and the site is left clean.
Trust dnf. It rolls back on failure. rpm leaves debris.
How to install a local RPM with dependency resolution
Here is how to install a local RPM while letting dnf handle dependencies.
sudo dnf install ./my-application-1.0-1.fc40.x86_64.rpm
# The ./ prefix tells the shell to look in the current directory.
# Without it, dnf might search the PATH for an executable named my-application.
# dnf reads the RPM metadata and calculates the full dependency tree.
# It fetches missing dependencies from enabled repositories before installing.
If the package is in another directory, use the absolute path.
sudo dnf install /home/user/Downloads/custom-driver-2.3-1.fc40.x86_64.rpm
# Absolute paths remove ambiguity about which file dnf should process.
# This is safer when running scripts or copying commands from documentation.
You can mix local files and repository packages in one command. This is a standard pattern for installing a local tool alongside its runtime requirements.
sudo dnf install git ./my-application-1.0-1.fc40.x86_64.rpm
# dnf treats repository names and file paths identically in the install list.
# This allows you to install a local RPM and ensure a specific repo package is present simultaneously.
# The transaction includes all items and resolves conflicts across the entire set.
Handling multiple RPMs with a local repository
If you have many RPMs, installing them one by one is inefficient. Create a local repository so dnf can resolve dependencies in bulk.
Install the tool to generate repository metadata.
sudo dnf install createrepo_c
# createrepo_c generates the metadata index required for dnf to treat a directory as a repository.
# This is faster than installing many RPMs individually because dnf resolves dependencies in bulk.
Generate the metadata for your directory.
createrepo_c /path/to/local-rpms
# This scans the directory and creates the repodata folder with dependency metadata.
# Run this command again whenever you add or remove RPMs from the directory.
Add the directory as a repository.
sudo dnf config-manager --add-repo=file:///path/to/local-rpms
# This adds a new repository definition pointing to the local directory.
# dnf will now index the RPMs in that directory and resolve dependencies against them.
Install packages by name.
sudo dnf install my-application
# dnf now treats the local directory as a source for packages.
# You can install packages by name instead of file path.
# This method is standard for internal software distribution and offline updates.
Verify the installation
Confirm the package is registered in the system database.
rpm -q my-application
# rpm -q queries the database for the package name.
# This confirms the package is registered in the system database.
# It returns the full NEVRA string if installed, or "not installed" otherwise.
Check the service if the package provides one.
systemctl status my-application.service
# systemctl status shows the current state and recent log lines for the unit.
# Always check status before restarting a service to see if it is already running.
# The output includes the active state, sub-state, and main PID.
Check the service status before assuming the install failed.
Common pitfalls and error messages
Dependency errors.
dnf will refuse to proceed and print Error: Transaction test error: package my-application-1.0-1.fc40.x86_64 requires libfoo.so.1()(64bit), but none of the providers can be installed. The conflict is intentional. Read the error before forcing. Enable the required repository.
sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
# This downloads and installs the RPM Fusion repository configuration.
# It adds new sources where dnf can find proprietary or non-free dependencies.
# Run dnf upgrade --refresh after enabling new repos to update the metadata cache.
GPG signature errors.
If you see error: my-application-1.0-1.fc40.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID 12345678: NOKEY, the key is missing. Import the key.
sudo rpm --import /path/to/pubkey.gpg
# This imports the public key into the RPM keyring.
# dnf will use this key to verify signatures for local files signed by this key.
# Never import keys from untrusted sources. A compromised key allows arbitrary code execution.
SELinux denials.
If the service fails to start, check SELinux. Fedora's strict policies often require explicit context adjustments for locally installed software.
journalctl -t setroubleshoot
# journalctl -t setroubleshoot filters logs for SELinux denial summaries.
# These summaries explain the denial in plain text and suggest fixes.
# Read these before disabling SELinux or creating custom policies.
Reset file contexts if the software was installed to a non-standard path.
sudo restorecon -Rv /opt/my-application
# restorecon resets file contexts to the defaults defined in the SELinux policy.
# The -R flag recurses into subdirectories. The -v flag prints changes.
# Use this after moving files or installing software outside standard paths.
Read the transaction summary before typing y.
When to use this versus alternatives
Use dnf install ./file.rpm when you have a local RPM and need dependencies resolved automatically. Use dnf install https://url/to/file.rpm when you want to install a remote RPM directly without downloading it manually first. Use rpm -ivh file.rpm only when you are in a recovery environment with no network access and you have manually verified every dependency is present. Use flatpak install file.flatpak when the application is distributed as a Flatpak and you prefer sandboxed isolation over system-wide integration. Use appimage execution when the vendor provides an AppImage and you want a portable binary without installation.
Pick the tool that matches your dependency situation.