DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
Docker

How to Fix TrueType Fonts Not Displaying in wkhtmltopdf

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The usual fix is to install the TrueType font inside the same environment that runs wkhtmltopdf, make sure Fontconfig can discover it, refresh the font cache, and then test with the production user and binary. A font installed on your workstation is not automatically available in a Docker image, remote server, queue worker, or serverless function. If Latin text works but some scripts show boxes, investigate fallback support separately; that is not the same problem as a missing font.

Start by identifying which failure you have

There are three distinct causes that are often reported as “the font does not work”:

  • Runtime visibility: the requested TTF file is absent, in an unscanned directory, or inaccessible to the account running wkhtmltopdf.
  • Fontconfig setup: the file exists, but Fontconfig’s configuration or cache is missing, stale, or pointed at the wrong location.
  • Rendering or fallback limits: the font is found, but the legacy Qt/WebKit engine cannot select the needed glyphs or handle a particular embedded-font pattern.

Do not begin by changing CSS randomly. Record the exact binary and environment first, then reproduce the smallest possible case in that same environment.

1. Record the renderer and execution context

Run these commands as the same user, inside the same container, VM, worker, or function image that creates the PDF:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
wkhtmltopdf --version
cat /etc/os-release
id
which wkhtmltopdf
fc-match "Your Font Family"
fc-list | head

Save the output with your bug report. Include the distribution release, package or build provenance, whether conversion is local or remote, and the exact HTML and CSS fixture. The wkhtmltopdf support documentation asks for a version and a reproducible test case because behavior varies substantially between builds.

The downloads documentation identifies 0.12.6 as a stable series released June 11, 2020, but that page’s release information is dated. Verify the project page before treating 0.12.6 as the current release, and test the binary actually deployed rather than assuming a package name identifies its build.

2. Prove the HTML and CSS independently

Open the exact HTML in a normal browser and inspect the computed font-family. Then create a minimal fixture that removes frameworks, JavaScript, and unrelated assets:

<!doctype html>
<meta charset="utf-8">
<style>
@font-face {
  font-family: "InvoiceTest";
  src: url("./fonts/InvoiceTest-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
}
body { font-family: "InvoiceTest", sans-serif; }
</style>
<p>ABC 123 — اختبار — пример</p>

Run it with the same command used in production:

wkhtmltopdf --encoding utf-8 test.html test.pdf

A browser rendering proves only that the browser can access its own files and supports the font. It does not prove that the PDF process has the same working directory, permissions, network access, or font implementation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Install the TTF where the renderer can see it

Use a font directory recognized by the target distribution’s Fontconfig setup. Common locations include system directories such as /usr/share/fonts or an application-owned directory explicitly included in Fontconfig. The correct path is distribution-dependent; inspect the image rather than copying a workstation path verbatim.

For a container, copy only fonts you are licensed to deploy:

COPY fonts/InvoiceTest-Regular.ttf /usr/local/share/fonts/invoice/
RUN fc-cache -v

If you install at runtime, make sure the service account can read every parent directory and the TTF itself. Proprietary fonts may restrict server redistribution, embedding, or conversion; check the license before adding them to an image or shipping them in a function layer.

An issue commenter reported that copying a font into a system font directory and running fc-cache -v fixed a remote-server case. That is a useful diagnostic example, not a universal guarantee.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Refresh and verify Fontconfig

After adding or replacing fonts, refresh the cache:

fc-cache -v
fc-match "InvoiceTest"
fc-match -f '%{file}n' "InvoiceTest"
fc-list : family file | grep -i InvoiceTest

fc-match should resolve to the intended file, not a generic substitute. Run these commands after switching to the production account if your application uses a dedicated user. A root shell seeing a font does not establish that an unprivileged worker sees it.

If your deployment bundles its own Fontconfig files, inspect the environment variables and paths used by that build. The project’s documentation notes that even statically linked Linux builds depend on runtime fonts, Fontconfig, and FreeType. Its Lambda example requires setting FONTCONFIG_PATH to the bundled configuration directory; the referenced configuration and font files must both be present in the deployed artifact.

export FONTCONFIG_PATH=/opt/fonts/etc/fonts
fc-match "InvoiceTest"
wkhtmltopdf --encoding utf-8 test.html test.pdf

Do not set FONTCONFIG_PATH to an empty or host-only directory. In a function or minimal image, copy the configuration, cache, and font files together, then verify them from inside the running package.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

5. Check file loading and URL details

Relative paths and working directories

A relative url() is resolved from the document’s base URL, which may differ when HTML is supplied through a temporary file or standard input. Use a correct base URL or an absolute local path appropriate to your deployment. Confirm that the process can read the path from its own namespace.

Local-file restrictions

If your fixture references local files, test the security options and packaging used by your build. Do not broadly enable access to the entire filesystem just to hide a path error. Grant only the directory needed by the document, and avoid processing untrusted HTML.

HTTP-hosted fonts

Network fonts add DNS, TLS, authentication, CORS, and timeout failure modes. For deterministic PDFs, package an appropriately licensed font with the application and verify it locally. If a remote URL is unavoidable, capture the response and status from the same runtime before blaming Fontconfig.

6. Distinguish missing fonts from fallback failures

If every glyph is substituted, first fix discovery. If Latin characters use the requested face but Arabic, Indic, CJK, emoji, or another script becomes boxes, the font may not contain those glyphs or the engine may fail to perform the required fallback.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A report against a 0.12 Linux build describes character-level fallback limitations. Test the exact version, operating system, text direction, and script. As an experiment, split runs into elements with explicit fonts that each cover their text:

<span class="latin">Invoice 123</span>
<span class="arabic" lang="ar">مرحبا</span>

Assign a known Arabic-capable family to the second class and compare the PDF. This is a workaround to validate, not a promise that all mixed-script layouts will work. Check shaping, line breaks, ligatures, right-to-left order, and copy/paste—not merely whether non-box glyphs appear.

7. Treat TTF-to-SVG changes as an experiment

One user report says that changing an embedded font reference from TTF to SVG fixed that individual case. It does not establish general SVG-font support or make the format a recommended replacement. If you test it, compare:

  • Whether the file loads in the exact wkhtmltopdf build.
  • Glyph coverage, shaping, and print quality.
  • PDF size and conversion time.
  • Font licensing and embedding permissions.
  • Behavior across every target platform.

Keep the TTF and SVG tests as separate fixtures so a successful result is reproducible and attributable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Docker and serverless deployment checklist

  1. Pin and print the wkhtmltopdf version during image builds.
  2. Copy licensed fonts into the image or function layer.
  3. Install the image’s Fontconfig and FreeType runtime packages.
  4. Run fc-cache -v after copying fonts.
  5. Set FONTCONFIG_PATH when using a bundled configuration, and verify that path inside the runtime.
  6. Run fc-match and a minimal conversion as the non-root service account.
  7. Log the resolved font filename and retain a small PDF fixture for regression tests.

A “static” Qt binary does not make the environment self-contained. The project explicitly lists runtime font configuration as a dependency. Minimal base images often omit exactly the libraries and configuration that a desktop installation supplies.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting by symptom

Symptom Likely cause Next check
Everything falls back to a generic face Font absent, unreadable, or not cached Run fc-match -f '%{file}n' 'Family' as the renderer user; inspect permissions and run fc-cache -v.
Works locally, fails in Docker Font or Fontconfig files are not in the image Exec into the image, list the font path, print wkhtmltopdf --version, and repeat the minimal fixture.
Works as root, fails in production Different HOME, cache, permissions, or environment variables Run fc-match and conversion under the service account.
Only some scripts show squares Coverage or fallback limitation Test explicit per-script fonts and the exact build; inspect shaping and direction.
Embedded font never loads Bad base URL, blocked local access, network or URL failure Replace it with a packaged local fixture and verify the resolved path.
Changing format appears to help Build-specific loading behavior Compare TTF and SVG output, size, quality, and licensing before adopting anything.

Performance, reliability, and security considerations

Font discovery and cache generation should happen at image-build or deployment time, not for every request. Keep the cache warm and avoid downloading fonts during a conversion. Use a short, deterministic fixture in health checks so a broken image fails before customer PDFs are produced.

wkhtmltopdf is legacy software. The project status page says Qt 4 has not been supported since 2015 and its WebKit has not been updated since 2012. That does not by itself identify a replacement or guarantee that changing builds will preserve layout. Treat upgrades as compatibility projects: render representative documents, compare pagination and glyphs, and test every target script.

Never feed untrusted HTML to this engine without isolation. The project cautions against processing untrusted HTML; local-file access, network requests, scripts, and resource exhaustion can create security and operational risks.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your actual requirement is a clean image or PDF of a web page rather than a wkhtmltopdf-generated document, ScreenshotNeo provides a single API request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. An MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.

cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo API documentation for options such as full-page capture, CSS-selector elements, device presets, custom CSS and JavaScript, waits, headers, cookies, blocking, PDFs, signed links, asynchronous jobs, and bulk capture. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Final verification sequence

  1. Print the exact wkhtmltopdf version and runtime identity.
  2. Run fc-match to prove the family resolves to the intended file.
  3. Confirm the font file, Fontconfig configuration, and cache exist inside the deployment.
  4. Convert a minimal fixture with the production command and account.
  5. Test every script and fallback case represented in real documents.
  6. Keep a regression PDF and repeat the test after image, package, or font changes.

Frequently Asked Questions

Does installing a TTF on my laptop install it for a server running wkhtmltopdf?

No. The font must exist and be discoverable in the server, container, worker, or function environment that launches wkhtmltopdf.

Why does fc-match return a font but the PDF still looks wrong?

Discovery only proves Fontconfig selected a file. The selected face may lack required glyphs, or the legacy renderer may have fallback or shaping limitations; test the exact script and build.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I switch from TTF to SVG fonts permanently?

No general guarantee supports that conclusion. One report found SVG helpful in one environment, so treat it as a controlled experiment and compare quality, size, compatibility, and licensing.

Quick Recap

Bestseller No. 2
Bestseller No. 4
Bestseller No. 5

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.