How-to guides/Errors & Debugging
Rendering Warning
Font not found: could not substitute 'CustomFont'

How to fix PDF font not rendering: could not substitute font

This warning means a font referenced in the PDF is not embedded and cannot be found on the system. The renderer falls back to a substitute font, producing garbled text, character replacement, or incorrect layout. The fix is to embed all required fonts before saving.

Why this happens

Fonts not embedded in the PDF

The PDF references fonts by name but does not include the font data. When the document is rendered on a system that does not have those fonts installed, the renderer must substitute a different font. Substitutes often have different metrics, leading to text overflow, layout shifts, and visual differences.

System font not found on the server

PDFs created on a developer's machine may reference fonts that are installed locally (e.g. a commercial typeface or a system font unique to macOS or Windows). On a Linux server these fonts are absent, causing the substitution warning.

Font subsetting removed required glyphs

Font subsetting reduces file size by including only the glyphs actually used in the document. If the PDF is later edited to add new characters that were not in the original subset, those glyphs are missing from the embedded font and cannot be rendered.

How to fix it

1

Embed all fonts before saving

Use PDFluent's embed_all_fonts() before calling save(). This walks every page and text object, finds the referenced fonts, and embeds the full font data into the PDF. The resulting file renders identically on any system.

use pdfluent::PdfDocument;

let mut doc = PdfDocument::open("with-missing-fonts.pdf")?;

// Embed all referenced fonts into the document
doc.embed_all_fonts()?;

doc.save("with-embedded-fonts.pdf")?;
2

Use subset fonts to balance file size and portability

For new documents, embed a subset of each font containing only the glyphs needed. This keeps file size reasonable while ensuring the document renders correctly everywhere.

use pdfluent::{PdfDocument, FontSubset};

let mut doc = Document::new();
let font = FontSubset::from_file("MyFont.ttf")?;

let mut page = doc.add_page((595.0, 842.0));
page.set_font(&font, 12.0);
page.draw_text(50.0, 750.0, "Hello, world!")?;

// Subset is embedded automatically on save
doc.save("output.pdf")?;
3

Check for missing fonts before rendering

In a pipeline that receives PDFs from external sources, check for missing fonts before passing documents to a renderer. This lets you embed fonts proactively or return a helpful error to the caller.

use pdfluent::PdfDocument;

let doc = PdfDocument::open("incoming.pdf")?;
let missing = doc.find_missing_fonts()?;

if !missing.is_empty() {
    eprintln!("Missing fonts: {:?}", missing);
    // Optionally embed system fonts as substitutes:
    // doc.substitute_missing_fonts(&FontDirectory::system())?;
}

Frequently asked questions