How font enumeration works
Enumeration just means listing out what's there. The classic technique draws some text using three generic fallback fonts (monospace, sans-serif, serif) and records the rendered width and height. It then redraws the same text asking for a candidate font, with the generic as a backup (e.g. "Calibri", monospace). If the size changes, the candidate font exists and was used; if it matches the fallback size, the font is not installed. Run this across a list of a few hundred fonts and you get the full installed set.
Newer variants skip the page's HTML entirely and measure with CanvasRenderingContext2D.measureText() on an offscreen canvas - a hidden drawing surface. That is faster and harder to tamper with. The result is hashed together with the other signals into the overall browser fingerprint.
Why scrapers get caught
A fresh Linux container running headless Chrome ships with a tiny, well-known font set (often just DejaVu and a couple of Noto families). Real Windows and macOS machines have dozens of system fonts plus whatever each installed application adds. Anti-bots keep a catalogue of these “default server” font sets and flag them on sight. Worse, a mismatch between the OS claimed in the User-Agent (the browser's self-reported identity string) and the actual font set - UA says Windows, fonts say Linux - is a flat contradiction that a lie detector will catch.
Faking the font list in JavaScript is fragile: the measurements still come from the real renderer, so claiming a font exists while measureText returns the fallback size is itself a giveaway. The durable fixes are to install a real font set at the OS/FontConfig level (FontConfig is the Linux system that manages fonts), or to use a patched browser like Camoufox.
Passing font checks without faking it
Because the measurements come from the real font rasteriser (the part of the system that turns a font into pixels), faking measureText or the font list in JavaScript is brittle - the list you claim and the glyph widths you actually measure drift apart, and that contradiction is the tell. The reliable fix is to make the font set genuine: install a font package at the OS / FontConfig level that matches the operating system your User-Agent claims, so a "Windows" identity really does carry Segoe UI, Tahoma and the rest of the expected Windows fonts.
This is exactly the kind of signal a patched browser like Camoufox handles deep in the engine rather than with a script injected into the page, keeping the rendered measurements and the reported font list in agreement. If you scrape through a managed web scraping API, fonts are part of the device profile the provider maintains, so you inherit a consistent set instead of the bare DejaVu-only fingerprint of a fresh Linux container.
