You downloaded the fonts, but nothing is using them
You extract a zip archive of Google Fonts or copy the Microsoft Core fonts from an old Windows drive. You double-click a .ttf file and the Font Viewer opens with a preview. You close it. You open LibreOffice Writer, GIMP, or Firefox, and the new typeface is nowhere in the dropdown. The system isn't broken. The font files just landed in a directory that fontconfig ignores. Linux does not scan your home folder or Downloads directory for typefaces. It expects them in specific hierarchical paths, then builds a binary cache that applications query at startup. Move the files to the right place, rebuild the cache, and every program will see them immediately. Place the files in the wrong directory and you will spend an hour wondering why your documents still render with the default sans-serif.
How the font subsystem actually works
Fedora uses fontconfig as the central registry for all typefaces. When an application requests a font, it does not scan the filesystem. It queries a compiled cache file that lives in /var/cache/fontconfig/. That cache is generated by scanning predefined directories. The hierarchy follows a strict precedence rule. User-local fonts override system fonts. System fonts override package-managed fonts. If you place a file in ~/Downloads, the cache builder never touches it. If you place it in ~/.local/share/fonts/, the next cache run registers it for your user only. If you place it in /usr/local/share/fonts/, it becomes available to every user on the machine.
The package manager owns /usr/share/fonts/. That directory contains only the fonts installed by RPM packages like google-noto-sans-fonts or liberation-fonts. Dropping manual files there breaks dnf database consistency and risks getting overwritten during a system upgrade. Stick to the local or user paths. The system will handle the rest. Always edit or add files in /etc/ or user directories. Never drop manual assets into /usr/lib/ or /usr/share/ unless you are building an RPM.
The cache builder runs automatically on boot, but it does not trigger when you copy a file mid-session. You must force a rebuild. Applications also load the font list into memory when they launch. They will not see new files until they are restarted. Run fc-cache -fv after every copy operation. Restart your editor before testing.
Install fonts for your user account
This is the default recommendation. It requires no root privileges, survives system upgrades, and keeps your personal typeface collection separate from the base installation. The XDG Base Directory Specification standardizes ~/.local/share/ as the correct location for user-owned data. Fonts belong there.
Create the user font directory if it does not exist yet. Copy your downloaded files into it. Force the font cache to rebuild and verify the output.
# Create the standard XDG fonts directory for the current user
mkdir -p ~/.local/share/fonts
# Copy TrueType or OpenType files from your downloads folder
cp ~/Downloads/*.ttf ~/.local/share/fonts/
cp ~/Downloads/*.otf ~/.local/share/fonts/
# Rebuild the font cache. -f forces a full scan, -v shows progress
fc-cache -fv
The -v flag prints each directory as it is scanned. You will see ~/.local/share/fonts listed with a count of newly registered faces. If the count matches your file list, the registration succeeded. Restart any application that was already open. Applications load the font list into memory when they launch. They will not see the new files until they are restarted. Keep your user font directory clean. Delete unused files and run the cache command again.
Install fonts system-wide
Use this path when you are managing a shared workstation, a lab machine, or a server that runs headless PDF generation tools. System-wide installation requires root access and places the files where every user account can read them. The /usr/local/share/ prefix is reserved for administrator-managed files that are not part of the base RPM distribution. This keeps your manual installations completely separate from package-managed fonts.
# Create a dedicated directory under the local hierarchy
sudo mkdir -p /usr/local/share/fonts/custom
# Copy the font files into the new system directory
sudo cp ~/Downloads/*.ttf /usr/local/share/fonts/custom/
sudo cp ~/Downloads/*.otf /usr/local/share/fonts/custom/
# Rebuild the system font cache with full verbosity
sudo fc-cache -fv
The dnf package manager will never touch this directory. You can safely add, remove, or update fonts here without triggering dependency conflicts or broken package states. If you ever need to purge the custom fonts, delete the directory and rebuild the cache. The system returns to its default state instantly. Never mix manual copies with RPM-managed paths. Trust the package manager for standard fonts. Keep manual installs isolated to /usr/local/ or ~/.local/.
Verify the installation worked
Do not guess whether the font registered. Query the cache directly. The fc-list command reads the same binary cache that applications use. Pipe it through grep to search for the exact family name or file path.
# List all registered fonts and filter for a specific family name
fc-list | grep -i "inter"
# Check if a specific file path is recognized by fontconfig
fc-list /home/youruser/.local/share/fonts/Inter-Regular.ttf
If the command returns the full path and the font style (Regular, Bold, Italic), the system recognizes it. If it returns nothing, the file is either corrupted, placed in the wrong directory, or contains a malformed font table. Open the file in the Font Viewer again. If the preview shows missing glyphs or crashes, the archive you downloaded is damaged. Redownload it from the source. Run fc-list before opening your editor. Verify the cache before troubleshooting applications.
Common pitfalls and what the error looks like
Font installation failures rarely throw terminal errors. The silence is the problem. fc-cache will run successfully even if it finds zero valid files. You will get a clean exit code and a cache that still lacks your new typeface.
The first culprit is file format confusion. Many modern foundries distribute variable fonts as .ttf or .otf files that contain multiple axes. Older applications like early versions of LibreOffice or certain terminal emulators struggle to parse them. If fc-list shows the font but your application does, the app lacks variable font support. Fall back to static instances or update the application.
The second culprit is duplicate family names. If you install a font named Arial alongside the system Liberation Sans fallback, fontconfig will attempt to alias them. You may see unexpected substitution behavior in documents. Check your aliases in ~/.config/fontconfig/fonts.conf if text rendering starts behaving strangely after adding new fonts.
The third culprit is GUI font managers. Third-party tools like gnome-font-viewer or standalone font managers often copy files to temporary directories or user-specific config paths that do not trigger a global cache rebuild. They work for previewing. They do not work for system-wide registration. Always use the terminal cache command when you need reliability.
When fc-cache fails to register a file, it prints a warning to standard error. You will see output like this:
Warning: cannot create directory `/var/cache/fontconfig/': Permission denied
Parsing configuration file `/etc/fonts/fonts.conf'...
Failed to load font file `/home/user/.local/share/fonts/broken-file.ttf': Invalid format
Permission errors mean you ran the command without sudo in a system directory, or your user cache directory has wrong ownership. Invalid format errors mean the file is not a valid TrueType or OpenType container. Fix the permissions or replace the file. Do not force cache generation over corrupted data. Clean the directory first. Rebuild the cache second.
When to use manual installation versus alternatives
Use manual directory placement when you need a specific typeface that is not available in the Fedora repositories. Use dnf install when the font family is packaged upstream and you want automatic updates and dependency resolution. Use the user-local path when you are working on a single account and want zero risk of affecting other users. Use the system-local path when you are provisioning a shared machine or a CI runner that requires consistent typography across multiple service accounts. Stick to RPM packages when you are managing a fleet of servers and need reproducible builds. Trust the package manager for standard fonts. Keep manual installs isolated to /usr/local/ or ~/.local/.