Font & DB tools

You installed a font and LaTeX cannot find it. This page exists to answer that one sentence. The awkward part is that each engine looks for fonts in a completely different way. pdflatex never consults the system fonts at all; it trusts only the font maps that updmap builds. XeTeX asks the operating system’s font machinery. LuaTeX consults a Lua database of its own that luaotfload builds. So “it shows up in fc-list but I cannot use it” is not a contradiction — you are simply looking at a different one of the three mechanisms. What follows arranges fc-list, fc-cache, updmap, kanji-config-updmap, luaotfload-tool and fmtutil by which layer of failure each one repairs.

How an engine finds a font: three separate mechanisms

The three-way split is simply the difference in when each engine was born, preserved intact. pdfTeX descends from 1980s TeX, when the operating system had no notion of a font catalogue at all. So the correspondence between a logical TeX name — a string like ptmr8r — and a real file is written down in a table called a font map, and updmap is what assembles it. XeTeX, from 2004 onwards, was designed to hang directly off the system’s font machinery: run otool -L on the xetex binary from the macOS build of TeX Live 2024 and you find CoreText linked in. LuaTeX resolves names in Lua, consulting the database that luaotfload builds. Write the same \setmainfont{...} under each, and that one line asks three different authorities.

EngineHow it looks for a fontCommand that repairs it
pdftexIgnores system fonts entirely; resolves .tfm logical names to files through a font mapupdmap-sys
xetexAsks the operating system; the macOS build is linked against CoreTextthe OS font manager
luatexResolves names in Lua, consulting the names database that luaotfload buildsluaotfload-tool --update
dvipdfmxNot typesetting but embedding: the map decides which fonts go into the PDFupdmap-sys / kanji-config-updmap-sys

fc-list and fc-cache are not TeX Live commands

Get this wrong and every judgement after it goes wrong too. fc-list, fc-cache and fc-match all belong to fontconfig, a separate project, and are not part of TeX Live. Search the TeX Live 2024 bin directory end to end and there is no executable beginning with fc-; the copies on this Mac were installed by Homebrew as fontconfig 2.18.2. They are still worth having, because they answer what fonts the system holds and where the files live. fc-list : family prints just the family names, and fc-list -f prints a chosen format such as file, family and style. On this machine the list came back with 2,799 entries.

terminal
fc-list : family | sort -u | wc -l         # how many families the system offers
fc-list -f '%{file}\n' :family=Menlo        # where the file actually is
fc-cache -fv ~/Library/Fonts               # rebuild the fontconfig cache

fc-match "NoSuchFontXYZ"
# Verdana.ttf: "Verdana" "Regular"          <- a substitute, not an error

There is a trap here that catches everyone once. fc-match never says “not found”. Hand it a name that does not exist and fontconfig still returns something: here, fc-match "NoSuchFontXYZ" answered Verdana.ttf: "Verdana" "Regular". That is a substitution, not a confirmation. Use fc-match to check whether a font is installed and it will always tell you yes. To actually decide, compare the family name that comes back against the one you asked for, or narrow the search with fc-list. On macOS there is a second caution. As the previous section showed, xetex is looking at CoreText, so appearing in fc-list is no guarantee that XeTeX can use the font. Conversely, on builds where XeTeX does search through fontconfig — Linux TeX Live, typically — running fc-cache after dropping a font into your font directory is exactly the right move.

updmap: what a single line of a font map actually says

A font map is plain text, one line per binding between a logical TeX name and a real file. updmap does not write those lines itself; it concatenates the .map files listed in updmap.cfg into psfonts.map for dvips and pdftex.map for pdftex and dvipdfmx. Counting updmap-sys --listmaps on this machine gives 389 declarations — 332 of them Map, 46 MixedMap, 11 KanjiMap. The concatenated psfonts.map is a single text file of 45,672 lines, close to 5.5 MB. A line inside it reads like this: the TeX-side name, the PostScript font name, a re-encoding instruction, and the actual files.

terminal
# one real line out of psfonts.map on this machine
ptmr8r NimbusRomNo9L-Regu " TeXBase1Encoding ReEncodeFont " <8r.enc <utmr8a.pfb

updmap-sys --listmaps            # every declared map, and which cfg declared it
sudo updmap-sys --enable Map myfont.map
sudo updmap-sys                  # rebuild psfonts.map and pdftex.map

What trips people up in practice is rarely the command but which configuration they are touching. In TeX Live 2024, plain updmap refuses to run at all: it answers updmap [ERROR]: Either -sys or -user mode is required. followed by updmap [ERROR]: In nearly all cases you should use updmap -sys. That refusal is a kindness, because the real trap lies just beyond it. The output of updmap --help says it outright: once updmap-user has been run even a single time, running updmap-sys no longer has any effect. A personal configuration file comes into existence and takes precedence from then on. On shared machines and in CI, standardise on updmap-sys, and reach for updmap-user only when you consciously mean to override the system settings. The sudo is needed because everything under /usr/local/texlive/2024 is owned by root.

kanji-config-updmap: choosing which Japanese font is embedded

There is a reason the choice of Japanese font has a command of its own. On the pLaTeX and upLaTeX route, which Japanese font gets embedded in the PDF is decided not at typesetting time but at the dvipdfmx step. You can therefore swap the embedded font afterwards without touching the manuscript, and kanji-config-updmap (from texjporg) is that switch; underneath it sets updmap’s jaEmbed option, formerly called kanjiEmbed. Start with status. On this machine it answered CURRENT family for ja: haranoaji (variant: -04) and then listed ipa and ipaex among the standby families. To change, pass the family name directly. As with updmap there is a -sys and a -user form, and on shared machines standardising on kanji-config-updmap-sys is the safe choice.

terminal
kanji-config-updmap-sys status
# CURRENT family for ja: haranoaji (variant: -04)
# Standby family : ipa
# Standby family : ipaex

sudo kanji-config-updmap-sys ipaex   # embed the IPAex family instead
sudo kanji-config-updmap-sys auto    # let it pick from what is installed

luaotfload-tool: why the first LuaTeX run is slow

What surprises people on their first LuaLaTeX run is the wait. The cause is luaotfload’s names database, built by scanning the font files on the system to map names onto files. On this machine it sits at TEXMFVAR/luatex-cache/generic/names/luaotfload-names.luc.gz, about 390 KB. The interesting part is that a failed lookup starts a rebuild on its own. Hand \setmainfont a name that does not exist and the log shows luaotfload | db : Reload initiated (formats: otf,ttf,ttc); reason: Font "NoSuchFontXYZ" not found. before stopping at ! Package fontspec Error: The font "NoSuchFontXYZ" cannot be found. So “LuaLaTeX cannot see the font I just installed” usually cures itself on one more run. To force it, luaotfload-tool --update rebuilds the database, announcing Font names database not found, generating new one. and This can take several minutes; please be patient. when there is nothing to start from.

terminal
luaotfload-tool --update              # rebuild the LuaTeX names database
luaotfload-tool --diagnose=environment # what luaotfload thinks its world looks like
ls "$(kpsewhich --var-value=TEXMFVAR)/luatex-cache/generic/names/"

fmtutil: rebuilding the .fmt an engine loads at startup

When you run pdflatex, the engine loads a format file such as latex.fmt before it begins any work. That file is a snapshot of the engine’s entire internal state at the moment it finished reading all of LaTeX — the trick that lets it start without re-reading thousands of lines of macros every time. fmtutil rebuilds those .fmt files. It is rarely needed: only after an update that touches a format, or when a .fmt is damaged and the engine stops before it can start. It is not something to run after every package install. For a single format, fmtutil-sys --byfmt pdflatex; for all of them, fmtutil-sys --all, which takes several minutes. The -sys and -user distinction works exactly as it does for updmap, and shared machines should standardise on -sys.

terminal
sudo fmtutil-sys --byfmt pdflatex   # rebuild one format
sudo fmtutil-sys --all              # rebuild every format (several minutes)
kpsewhich --var-value=TEXMFVAR      # where the .fmt files end up

Which command for which symptom

CommandReach for it when
fc-list : familyYou want to confirm first whether the system really has the font, and under what name
luaotfload-tool --updateOnly LuaLaTeX cannot find the font, and a second run does not fix it
updmap-sys --enable MapA Latin-script font package was installed by hand but the PDF still shows the old font
kanji-config-updmap-sys statusOnly the Japanese text in the PDF is wrong; check the current jaEmbed first
fmtutil-sys --byfmtThe engine stops before typesetting begins because it cannot load its format
mktexlsrA file was placed in TEXMFLOCAL and is still not found; see the build-tools page

One small tool in the margin of this map, to finish. TeX Live ships a command called albatross, described by its man page as a tool for finding fonts that contain a given Unicode glyph — and it relies on fontconfig internally, another place where a TeX-world tool calls out to fontconfig. Running it here, though, stopped at Unable to locate a Java Runtime. It needs a Java runtime, so install one separately if you want it. mktexlsr and texhash, along with kpsewhich, are covered in detail on the build-tools page.