Your Build Depends on Google Fonts Being Up. It Shouldn't.

A production deploy failed. The commit touched one React component and no styling. The build log had twenty-four errors, all variations of:
Error: Turbopack build failed with 24 errors:
- Execution of <NextFontGoogleFontFileReplacer as ImportMappingReplacement>::result failed
- Error while looking up import map: next/font/google queries have exactly one entry
at <unknown> ([next]/internal/font/google/ibm_plex_sans_19433e6b.module.css:48:8)
Nothing in the diff could have caused that. The same commit built cleanly on a second attempt after clearing the build cache. A different push, with the identical code, failed on CI for the same reason.
What is actually going on
Modern font loaders like next/font/google do not add a <link> to a font CDN at runtime. They
download the font files at build time, hash them, and emit them as local assets. That is a real
improvement: no third-party request on page load, no layout shift waiting for a remote stylesheet, no
privacy problem handing every visitor's IP to another company.
The cost is rarely stated: your build now makes network calls to fonts.googleapis.com and
fonts.gstatic.com, and if those calls fail, your build fails. A third party is in your release
pipeline.
Most of the time you never notice, because the fetch is cached. You notice when:
- the font service is briefly unavailable or rate-limits your build agent
- your CI runs on shared IPs that are being throttled
- the build runs in a network-restricted environment with no egress to those hosts
- a restored build cache is partially populated, so the CSS resolves but the font files do not
That last one explains why ours failed and then passed. The build cache is restored between runs for speed. A cache carrying font stylesheets without the matching files produces exactly this error — and a clean cache fixes it, which makes the failure look random.
Immediate recovery
If you are blocked right now:
rm -rf .next && npm run build
On a hosted platform, trigger a rebuild with the cache disabled. Most offer this: an environment variable, a "clear cache and deploy" button, or a CI flag. That turns a mysterious failure into a two-minute fix — provided you recognise what you are looking at, which is the whole problem.
The durable fix: self-host the files
Download the font files once, commit them, and load them from disk. The build then has no external dependency at all.
import localFont from "next/font/local";
export const sans = localFont({
src: [
{ path: "./fonts/IBMPlexSans-Regular.woff2", weight: "400", style: "normal" },
{ path: "./fonts/IBMPlexSans-SemiBold.woff2", weight: "600", style: "normal" },
],
display: "swap",
variable: "--font-sans",
});
You get the same output — local assets, no runtime third-party request — with none of the build-time fetching. The trade-offs are honest ones:
- You own updates. A font revision no longer arrives automatically. For a brand typeface, that is usually what you want.
- You must check the licence. Most open fonts permit redistribution; confirm for yours before committing the files.
- You pick the subset. Ship only the weights and character ranges you use, or you will carry files nobody downloads. Subset with a tool rather than shipping the full family by reflex.
The broader audit worth doing
Fonts are one instance of a general pattern: things that look like assets but are actually build-time network calls. Go looking for the others in your pipeline:
- font loaders that fetch at build (
next/font/googleand equivalents) - icon or image pipelines that pull from a remote source during build
- schema, type or client generation that hits a live API endpoint
- a package manager resolving from a registry with no lockfile integrity pinning
- container images pulled by a mutable tag like
latest, so yesterday's build and today's differ - CI actions referenced by branch rather than by commit SHA
For each, ask one question: if this host is down for an hour, can we ship a fix? Anything where the answer is no belongs either vendored into the repository or cached in a store you control.
That matters most precisely when it hurts most. The day you need to ship an urgent fix is the day you discover your release path depends on a service you have no relationship with and no status page for.
Make the failure legible
Whatever you decide, leave a note where the next person will hit it:
// Fonts are self-hosted deliberately: next/font/google fetches at BUILD time, which
// put fonts.gstatic.com in our release path and failed a production deploy on
// 2026-10-03 with no code change to blame. Files live in ./fonts and are updated
// by hand. See docs/fonts.md before changing this.
The error message you get from a font-fetch failure says nothing about networks or third parties — it talks about import maps and CSS line numbers. It is close to unsearchable unless you already know what it means. A comment at the point of use is worth more than a wiki page nobody finds.


