mkfontdir writes the fonts.dir file an X font directory needs, and a missing or stale one is why a font quietly refuses to show up. You will build that index, check it, and see when fonts.scale, fonts.alias and encodings.dir get involved too. Allow about ten minutes.
You need a shell, a readable font directory and the xfonts-utils package. The examples use mkfontdir 1.0.7 from Debian package xfonts-utils version 1:7.7+6build3 installed on this machine.
mkfontdir does not install fonts and does not add a directory to an X server's font path. It reads font files in each directory you name and writes index files into those same directories. Work in a directory you own first, then repeat the operation on a system font directory only once you are ready to change it.
$ command -v mkfontdir
/usr/bin/mkfontdir
$ dpkg-query -W -f='${Package} ${Version}\n' xfonts-utils
xfonts-utils 1:7.7+6build3
The recognised formats depend on the local configuration, but the manual names PCF, SNF and BDF as the usual types. When one font exists in several formats, the command prefers PCF, then SNF, then BDF. Compressed PCF files such as .pcf.gz are normal on a packaged Linux system.
Checkpoint: Confirm the target contains the font files you expect before generating anything:
$ find /path/to/x-fonts -maxdepth 1 -type f
/path/to/x-fonts/6x13.pcf.gz
/path/to/x-fonts/DejaVuSans.bdf
Pass one or more directory names. With no options, the command scans for fonts and creates or replaces fonts.dir in each one:
$ mkfontdir /path/to/x-fonts
$ sed -n '1,6p' /path/to/x-fonts/fonts.dir
2
6x13.pcf.gz -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1
DejaVuSans.bdf -dejavu-deja vu sans-medium-r-normal--0-0-0-0-p-0-iso10646-1
The first line is the number of indexed fonts. Each later line has the file name followed by the X font name. Your names and count will match your own files, so treat the sample above as its shape, not a result to copy literally.
Font properties supply the name, with the file name minus its suffix as a fallback. A font file with a misleading name can still get a useful X name; a file that is not a supported font will not become a valid entry just because it has a familiar suffix.
Safety warning: generating the index changes fonts.dir. If an existing index is worth keeping, copy it before scanning:
$ cp --preserve=all /path/to/x-fonts/fonts.dir /path/to/x-fonts/fonts.dir.backup
$ mkfontdir /path/to/x-fonts
To undo this example, restore the backup with mv /path/to/x-fonts/fonts.dir.backup /path/to/x-fonts/fonts.dir after checking it is the right file. That replacement is itself a state change, so do not run it against a directory you are not sure about.
Check that the file exists, that its declared count agrees with the number of entries, and that every listed file is present:
$ test -s /path/to/x-fonts/fonts.dir && echo 'fonts.dir exists and is non-empty'
fonts.dir exists and is non-empty
$ awk 'NR == 1 { expected = $1; next } NF { actual++ } END { print "declared=" expected, "entries=" actual; exit expected != actual }' /path/to/x-fonts/fonts.dir
declared=2 entries=2
$ while read -r file name; do test -f "/path/to/x-fonts/$file" || echo "missing: $file"; done < <(tail -n +2 /path/to/x-fonts/fonts.dir)
The last loop should print nothing. It checks the relative file names recorded by the index, not whether an X server can already load the font. If the count is wrong or a file is missing, inspect the directory and regenerate the index after fixing the files. Do not hand-edit the generated list just to hide a missing font.
Scalable font files often do not contain a complete X font name. A fonts.scale file supplies those names, and mkfontdir copies its entries into fonts.dir. Generate fonts.scale with mkfontscale, review it, then run mkfontdir:
$ mkfontscale /path/to/x-fonts
$ sed -n '1,6p' /path/to/x-fonts/fonts.scale
$ mkfontdir /path/to/x-fonts
Do not assume an empty or stale fonts.scale is harmless: it can leave scalable fonts out of the final index, or preserve names that no longer describe the files. Treat it as an input document. Check its paths and names before rebuilding fonts.dir.
fonts.alias is different again. It maps convenient names to existing font-name patterns and is read by the X server or font server, not written by mkfontdir. Lines beginning with ! are comments. Keep it separate from the generated index so a later rebuild does not erase your intentional names.
If clients need encoding files, provide their directories with -e. The command scans each one and writes encodings.dir into every font directory named on the command line:
$ mkfontdir -e /usr/share/fonts/X11/encodings /path/to/x-fonts
$ sed -n '1,6p' /path/to/x-fonts/encodings.dir
-e; earlier encoding directories take precedence over later ones. Keep that order visible in scripts and review it whenever a package or font tree changes.-r before a particular -e when you need that directory kept relative; the option only applies to subsequent -e options.-p PREFIX. The prefix is used exactly as supplied, so add a trailing slash yourself if the resulting path needs one.-n when you want encoding indexes without scanning fonts or writing font directory files.$ mkfontdir -n -e /usr/share/fonts/X11/encodings /path/to/x-fonts
$ test -s /path/to/x-fonts/encodings.dir && echo 'encodings.dir exists'
encodings.dir exists
Use -x SUFFIX to ignore files of a particular type; the suffix is an exclusion value, not a new font format:
$ mkfontdir -x .bdf /path/to/x-fonts
Only use -x when you have a reason to prefer the other available format. Excluding BDF can remove a fallback that would otherwise be selected. If a generated index unexpectedly loses entries, rerun without -x and compare the counts.
Do not use sudo for a directory you own. A system directory such as /usr/share/fonts/X11/misc normally needs elevated privileges to rewrite its index:
$ sudo mkfontdir /usr/share/fonts/X11/misc
Warning: that command changes a shared resource used by X clients. Take a backup first, make the smallest intended change, and verify the resulting file. If the index is wrong, restore the known-good backup rather than deleting font files. The command itself does not restart the X server or change its font path; applications may need to reconnect, or be told to refresh their font path separately.
mkfontdir is installed and its version-specific behaviour is understood.fonts.dir exists in the intended directory, with a correct count and present files.fonts.scale was checked when scalable fonts are present.fonts.alias stays an intentional, hand-maintained file.encodings.dir was only generated when encoding files are needed, precedence checked.