You need the files, not the package
You downloaded a custom RPM from a vendor or a third-party repository. You need to check the contents of a configuration file before applying it, or you want to grab a single binary to test in a sandbox. Installing the package pulls in dependencies you do not want, modifies the RPM database, and might overwrite existing configs. You just need the files.
This scenario happens often. You might be recovering a deleted system config, auditing a binary for a security review, or inspecting a package before deploying it to a fleet of servers. The package manager is designed to install, not to inspect. Using dnf install or rpm -ivh for inspection is the wrong tool. It triggers transactions, runs scripts, and changes system state. You need a read-only extraction that leaves the host untouched.
What is inside an RPM
An RPM file is not a simple zip archive. It contains a header with metadata, signatures, and dependency information, followed by a compressed CPIO archive holding the actual files. The rpm tool reads the header to manage installations, verify checksums, and handle dependencies.
Think of the RPM like a shipping crate with a detailed manifest stapled to the outside. The manifest tells the warehouse robot where to put the crate, what tools it needs, and what other crates must be nearby. The rpm command is the robot. It reads the manifest and moves the crate.
To get the files out without triggering the installer, you need to bypass the manifest and open the crate directly. rpm2cpio strips the header and outputs the raw CPIO stream. cpio reads that stream and writes the files to disk. This pipeline gives you the contents without the database overhead, dependency checks, or post-install scripts.
rpm2cpio is part of the core rpm package. It is installed by default on every Fedora system. cpio is a standard utility available in the base environment. You do not need to install extra tools to perform this extraction.
Extract everything to a safe directory
Always extract RPMs into a temporary directory. Extracting to your home folder or the current working directory can clutter your workspace and cause permission issues if the package contains files owned by root. A temporary directory keeps the extraction isolated and easy to clean up.
Here is how to create a temporary directory and extract the full contents of an RPM into it.
tmpdir=$(mktemp -d)
# mktemp -d creates a unique temporary directory and prints its path
# Storing the path in a variable lets you reuse it for extraction and cleanup
# This avoids hardcoding paths and prevents collisions with other processes
rpm2cpio package.rpm | cpio -idmv -D "$tmpdir"
# rpm2cpio strips the RPM header and outputs the raw CPIO archive stream
# cpio reads the stream from stdin and extracts the files
# -i tells cpio to enter extraction mode
# -d creates parent directories as needed to match the archive paths
# -m preserves the original modification times from the package
# -v prints each filename as it is extracted so you can track progress
# -D "$tmpdir" sets the destination directory for the extraction
The files will appear in the temporary directory, preserving their relative paths from the package. If the RPM contains /etc/nginx/nginx.conf, you will find it at $tmpdir/etc/nginx/nginx.conf. The leading slash is part of the absolute path in the package, but cpio extracts relative to the destination directory.
Extract to a temp directory. Your home folder is not a dumping ground.
Extract specific files
You often do not need the entire package. You might only want a configuration file or a specific library. cpio allows you to filter the extraction by specifying paths. This saves time and disk space, especially for large packages like glibc or kernel.
Here is how to extract only specific files from the RPM archive.
rpm2cpio package.rpm | cpio -idmv 'etc/myconfig.conf' 'usr/bin/mytool'
# The path must match the archive structure exactly
# cpio ignores the leading slash in RPM archives, so use 'etc/...' not '/etc/...'
# You can pass multiple paths to extract several files in one command
# -i -d -m -v flags work the same as the full extraction
The path you pass to cpio must match the internal structure of the archive. RPM archives store paths relative to the root, so the leading slash is stripped. If you pass /etc/myconfig.conf, cpio will look for a file literally named /etc/myconfig.conf in the current directory, which does not exist. It will fail with an error.
Drop the leading slash. CPIO will reject it every time.
Verify the extraction
After extraction, verify that the files landed correctly and the paths match your expectations. This step catches errors early, especially if you are scripting the extraction or recovering a critical config.
Here is how to list the extracted files and confirm the structure.
find "$tmpdir" -type f | head -20
# List the first 20 files to verify extraction without flooding the terminal
# Use 'ls -R' if you prefer a tree-like view of the directory structure
# Check that the filenames and paths match what you expect from the package
If you are recovering a deleted system file, compare the extracted file with the package metadata to ensure you have the correct version. The rpm -qlp command lists the files in the RPM without extracting them. This is useful for cross-referencing.
Check the list before you extract. rpm -qlp is faster than unpacking.
Common pitfalls
The leading slash error
The most common mistake is passing a path with a leading slash to cpio. If you run rpm2cpio package.rpm | cpio -idmv '/etc/foo.conf', you will see this error:
cpio: cannot stat '/etc/foo.conf': No such file or directory
cpio interprets the argument as a path relative to the current directory. Since there is no directory named /etc inside your current folder, it fails. Always omit the slash. Use etc/foo.conf instead.
SELinux contexts
Extracted files retain the permissions and ownership stored in the archive, but they do not retain SELinux contexts. If you move the extracted files to system directories like /etc or /usr/lib, SELinux will label them based on the default policy for that path. However, if the extraction process or manual moves disrupt the labeling, services might refuse to read the files.
If a service fails to start after you replace a config file with an extracted version, check the SELinux context. Use restorecon to reset the context to the policy default.
restorecon -Rv /etc/extracted-config/
# -R processes the directory recursively
# -v prints the changes so you can see which files got relabeled
# SELinux policies define the correct context based on file path, not extraction source
Run restorecon after moving files. SELinux does not care how you got the file there.
Permissions and ownership
RPMs often contain files owned by root or with restrictive permissions. If you extract as a standard user, you might not be able to write to the destination if you choose a system directory. Always extract to a user-writable location like a temp directory or your home folder. If you need to move files to /etc, use sudo only for the move operation, not the extraction.
Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. If you extract a config to /etc, ensure it has the correct ownership and permissions before the service reads it.
Why not rpm -ivh --root?
Some guides suggest using rpm -ivh --root /tmp/extract to extract files. This forces the RPM database to initialize in a fake root. It is slow, requires write access to the target, and can fail if the package has complex post-install scripts that expect a real system. rpm2cpio is lighter, faster, and safer for simple extraction. It does not touch the database or run scripts.
When to use this vs alternatives
Choose the right tool based on your goal. Extraction is not always the best approach.
Use rpm2cpio when you need to extract files quickly without installing extra tools. Use rpm2archive when you prefer working with tarballs and have the utility installed. Use dnf download when you need to fetch the RPM from a repository before extracting. Use rpm -qlp when you only want to list files and do not need to extract anything. Use dnf reinstall when you want to restore a package cleanly and update the RPM database. Use rpm -ivh --test when you want to check for dependency conflicts without installing.