Inspect PDF Fonts and Embedding with pdffonts
You will finish with a repeatable way to see which fonts a PDF uses, whether each font is embedded, whether it is a subset, and whether it carries an explicit ToUnicode map. The examples use pdffonts from Poppler 24.02.0, supplied here by Ubuntu package poppler-utils version 24.02.0-1ubuntu9.9.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a readable PDF and a shell. The inspection commands are ordinary user commands and do not need sudo. This guide reads PDFs only: it does not repair fonts, rewrite a document or change system font configuration.
1. Check the installed command
Confirm that the command is the Poppler utility you expect, then read its local help. This catches machines where the package is missing or a different executable is earlier in PATH:
$ command -v pdffonts
/usr/bin/pdffonts
$ dpkg-query -W -f='${Package} ${Version}\n' poppler-utils
poppler-utils 24.02.0-1ubuntu9.9
$ pdffonts -v
pdffonts version 24.02.0
Your package revision and copyright lines may differ. The important check is that the version is printed and the executable is the one you intended to run. If dpkg-query reports that poppler-utils is not installed, install it through your normal package-management process before continuing.
Checkpoint
You have a readable PDF path and know which pdffonts binary will inspect it.
2. List every font in a PDF
Pass the PDF as the final argument. Use a path that names an existing file rather than relying on a shell wildcard that could select the wrong document:
$ pdffonts /path/to/document.pdf
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
TWYWUS+NimbusSanL-Bold Type 1 Custom yes yes yes 105 0
KZEACY+NimbusRomNo9L-Regu Type 1 Custom yes yes yes 109 0
The exact rows depend on the PDF. A font can appear only once even when it is used on many pages. Conversely, one family can appear as several entries if the PDF stores different styles, encodings or subsets. A successful command normally prints a header followed by zero or more font rows.
The name is the name stored in the PDF. A prefix such as TWYWUS+ commonly identifies a subset, so do not assume that the visible text after the plus sign is the complete embedded font. The object ID is the PDF font dictionary object number and generation, useful when correlating this report with a PDF diagnostic tool.
3. Read the columns that affect portability
Focus on these fields when checking whether a PDF can be opened or extracted reliably on another machine:
typeidentifies the stored font form, such as Type 1, Type 1C, TrueType, Type 3, CID Type 0C or CID TrueType.encodingshows the encoding reported by the PDF, such asCustom. It is not a promise that every text extractor will interpret the file identically.embisyeswhen the font is embedded. Anovalue means the reader may need a local substitute.subisyeswhen the entry is a subset rather than the complete font.uniisyeswhen an explicit ToUnicode map is present.nocan make text extraction harder, but it does not by itself prove that extraction is impossible.
Embedded and subsetted are separate properties. A row can have both emb yes and sub yes, which is common for documents that carry only the glyphs they use. For a hand-off or archival review, record the rows rather than treating one column as a complete quality verdict.
4. Restrict the inspection to a page range
Use -f for the first page and -l for the last page. This is useful when a large PDF has a suspicious page or when you want to compare a cover with the main body:
$ pdffonts -f 1 -l 1 /path/to/document.pdf
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
TWYWUS+NimbusSanL-Bold Type 1 Custom yes yes yes 105 0
The range changes which pages are examined; it does not modify the PDF and it does not renumber the object IDs. Replace 1 with positive page numbers that exist in your document. If a font is used only outside the selected range, it will not appear in that range's report. Run the unrestricted command as well when you need the document-wide inventory.
Checkpoint
Compare a full report with a narrow report before concluding that a font is absent. Page scope is an easy source of false assumptions.
5. Inspect a PDF arriving on standard input
Use a single hyphen as the PDF argument when another program or a pipeline supplies the PDF bytes:
$ cat /path/to/document.pdf | pdffonts -
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
TWYWUS+NimbusSanL-Bold Type 1 Custom yes yes yes 105 0
For a simple file, the direct path is clearer. The standard-input form is useful when the PDF is already being streamed, but keep diagnostics separate from the data source. Do not pipe arbitrary untrusted input into a privileged process, and do not use sudo just because the source is a pipe.
6. Find missing-font substitutions
Add -subst to ask Poppler which substitute fonts it will use for non-embedded fonts:
$ pdffonts -subst /path/to/document.pdf
name object ID substitute font substitute font file
------------------------------------ --------- ------------------------------------ ------------------------------------
An empty table means this PDF did not produce a substitution row for the installed Poppler run. It is not a guarantee that every viewer on every platform has the same result. If rows appear, keep the substitute name and file in your report. A substitution can alter layout, glyph appearance or text metrics, so inspect the rendered pages as well as the table.
Do not confuse -subst with embedding fonts. It reports the fallback Poppler would use; it does not add that font to the PDF and does not repair the document.
7. Handle passwords and failures safely
An encrypted PDF may need a user password supplied with -upw. The owner password uses -opw, which the manual says bypasses PDF security restrictions:
$ pdffonts -upw 'USER_PASSWORD' /path/to/encrypted.pdf
name type encoding emb sub uni object ID
------------------------------------ ----------------- ---------------- --- --- --- ---------
Do not put a real password in shell history, a shared terminal transcript or a process listing. Prefer an isolated session and clear any history entry according to your shell's normal procedure. Treat the owner password as security-sensitive authority: use it only when you are authorised to bypass the document's restrictions.
If the file cannot be opened, check the path and read permission without changing anything:
$ test -r /path/to/document.pdf && echo readable
$ pdffonts /path/to/document.pdf
$ printf 'exit status: %s\n' "$?"
exit status: 0
The documented exit statuses distinguish an input-open failure, output-open failure, permission failure and other errors. A non-zero result is a reason to investigate the file, password, permissions or PDF structure, not to run the command as root by reflex.
Done means
- You checked the installed Poppler version and command path.
- You recorded the full font table, including
emb,subanduni. - You used page limits only when a page-scoped question required them.
- You know how to inspect a PDF from standard input and check substitutions.
- You treated passwords as sensitive and did not change the PDF or system configuration.