Next.js 'Failed to Fetch' Google Fonts Behind a Corporate Proxy: I Tested Every Fix
NODE_EXTRA_CA_CERTS fixes it under webpack and does nothing under Turbopack. I ran nine builds through an intercepting proxy on Next.js 16.1 and 16.3 — the fix that works depends on your version.
If your Next.js build says it failed to fetch a font from Google Fonts, and you're behind Zscaler, Netskope or any company proxy that inspects HTTPS, the error probably looks like this:
Failed to fetch `Geist` from Google Fonts.
Error while requesting resource
There was an issue establishing a connection while requesting
https://fonts.googleapis.com/css2?family=Geist:wght@100..900&display=swapThe usual corporate-proxy fix is to point NODE_EXTRA_CA_CERTS at your company's root certificate. Under Turbopack, that does nothing, and the right fix depends on which Next.js 16 release you're on — the setting most answers point to was removed in 16.2.
I didn't want to guess at this, so I tested it. I built a local proxy that intercepts HTTPS the same way a corporate gateway does, signed with a throwaway test certificate authority, and ran nine production builds through it: six on this site (Next.js 16.1.1, three Google fonts) and three on a minimal Next.js 16.3.6 app. Windows 11, Node 22. The test CA lived in a temp folder and was never installed into the system store.
The results
Next.js 16.1.1, all builds through the proxy:
| Test | Bundler | Settings | Result |
|---|---|---|---|
| A | Turbopack | NODE_EXTRA_CA_CERTS | ❌ Failed |
| B | webpack | NODE_EXTRA_CA_CERTS | ✅ Passed |
| C | Turbopack | System-certs switch on | ❌ Failed |
| D | Turbopack | System-certs switch on + SSL_CERT_FILE | ✅ Passed |
| E | Turbopack | SSL_CERT_FILE only | ❌ Failed |
| F | Turbopack | Switch in next.config.ts + SSL_CERT_FILE | ✅ Passed |
Next.js 16.3.6:
| Test | Settings | Result |
|---|---|---|
| 1 | Nothing | ❌ Failed |
| 2 | NODE_EXTRA_CA_CERTS + SSL_CERT_FILE + the old switch's env var | ❌ Failed |
| 3 | Old switch in next.config.mjs + SSL_CERT_FILE | ❌ Failed, plus a config warning |
Tests A and B are the key pair: same machine, same proxy, same certificate setting — only the bundler changed. Webpack trusted the test CA on all 17 font requests. Turbopack rejected it on every one. The proxy logged the same rejection each time: ERR_SSL_TLSV1_ALERT_UNKNOWN_CA, meaning the client didn't recognise the certificate authority.
Why NODE_EXTRA_CA_CERTS can't fix 'Failed to fetch' under Turbopack
NODE_EXTRA_CA_CERTS is a Node.js setting. It only affects network requests made by Node.
Under webpack, next/font downloads Google Fonts from Node, so the variable applies — that's test B. Under Turbopack, the download is done by Turbopack itself, in Rust, using its own HTTP client. That client never reads Node's settings. As the person in the original GitHub report put it, the standard variables NODE_EXTRA_CA_CERTS and SSL_CERT_FILE "don't configure Turbopack's Rust-based components."
Next.js 16 builds with Turbopack by default, so many teams hit this the day they upgrade. Their certificate setup didn't change; the code doing the download did.
One thing Turbopack does honour is the proxy address. It follows the standard HTTP_PROXY / HTTPS_PROXY convention, and in every test the request reached my proxy. So the failure is never "can't find the proxy". It's "doesn't trust the certificate the proxy presents".
Fix for Next.js 16.0 and 16.1: turn on system certificates
On these versions, Turbopack trusts its own bundled list of public certificate authorities by default and ignores your operating system's store. Your company's root certificate is almost certainly in the OS store, not in Turbopack's list.
The fix is an experimental option, added in mid-2025:
// next.config.ts — Next.js 16.1 and earlier only
const nextConfig = {
experimental: {
turbopackUseSystemTlsCerts: true,
},
};
export default nextConfig;Or set it for every project on the machine, which is handy for CI:
NEXT_TURBOPACK_EXPERIMENTAL_USE_SYSTEM_TLS_CERTS=1 next buildOn 16.1 the error message itself recommends this — it ends with "It looks like this error was TLS-related. Try enabling system TLS certificates…"
With the switch on, Turbopack loads the operating system's certificates. On a company laptop where IT has installed the root certificate, that's the whole fix.
What tests C, D and E add: with the switch on, Turbopack also honours SSL_CERT_FILE — the standard variable for "use the certificates in this file". My test CA wasn't in the Windows store, so the switch alone failed (C). The switch plus SSL_CERT_FILE pointing at the CA passed (D and F). SSL_CERT_FILE without the switch failed (E).
That's useful on build servers and Docker images, where you often have the company .pem file but no way to install it into the system store. It also explains why SSL_CERT_FILE "didn't work" for people who tried it on its own: it only counts once the switch is on.
Fix for Next.js 16.2 and later: the OS store is the default
In January 2026, the Next.js team removed the option. From 16.2, Turbopack verifies certificates through the operating system by default, so the switch is no longer needed. The pull request says Turbopack "should now pick up and work with system certs by default, and we no longer depend on shipping our own blob of trusted PKI roots."
In practice:
If your company's root certificate is in the OS trust store, 16.2+ should just work with no config at all. On most managed company laptops it already is, because the browser needs it too.
If it isn't, environment variables won't rescue you. On 16.3.6, test 2 set NODE_EXTRA_CA_CERTS, SSL_CERT_FILE and the old switch's environment variable together, and the build still rejected the certificate. Installing the root into the system store is the fix.
Remove the old option from your config. In test 3 it was simply ignored, with this warning:
⚠ Invalid next.config.mjs options detected:
⚠ Unrecognized key(s) in object: 'turbopackUseSystemTlsCerts' at "experimental"Two caveats, to be precise about what I proved. I didn't install the test CA into Windows' real trust store, because that's a security change to a working machine — so the "it just works" case on 16.2+ is based on the Next.js pull request, not my own test. And I tested on Windows only. On Linux, a follow-up change also bundles public roots as a fallback for minimal container images, but your company's root still has to be added to the system store, the same way you'd add it for any other tool.
The 16.3 error message points you the wrong way
The newer error text changed:
Failed to fetch Geist from Google Fonts.
If you are offline or behind a proxy, self-host the font with next/font/local,
or set HTTP_PROXY/HTTPS_PROXY so Next.js can reach fonts.googleapis.com.The "TLS-related" hint is gone, and the advice is to set HTTPS_PROXY. I already had HTTPS_PROXY set in every one of these tests, and the request did reach the proxy. If you're behind an intercepting proxy, the proxy setting is rarely the problem. Certificate trust is. The first suggestion in that message — self-hosting — is the one that works everywhere.
The fix that works on every version: self-host the font
Every fix above is about making the build trust your proxy. The cleaner option is a build that doesn't fetch fonts from the internet at all.
Google Fonts in Next.js are downloaded at build time — the docs note the font files are "downloaded at build time and self-hosted with the rest of your static assets". Visitors never contact Google either way. So bundling the font file in your repo changes nothing for users and removes a network dependency from every build.
If you're using Geist — the create-next-app default and the font in most of these error reports — Vercel publishes it as an npm package that already does this:
npm install geist// app/layout.tsx — replaces the next/font/google import
import { GeistSans } from "geist/font/sans";
import { GeistMono } from "geist/font/mono";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={`${GeistSans.variable} ${GeistMono.variable}`}>
<body className={GeistSans.className}>{children}</body>
</html>
);
}Under the hood the package uses next/font/local with .woff2 files it ships. For any other Google font, do the same yourself: download the .woff2 once, commit it, and load it locally.
import localFont from "next/font/local";
const spaceGrotesk = localFont({
src: "./fonts/SpaceGrotesk-Variable.woff2",
variable: "--font-space-grotesk",
weight: "300 700",
});You lose nothing visible and gain a build that passes on a plane, in a locked-down CI runner and behind any proxy. Check the font's licence before committing it — Google Fonts are open-licensed, but check anyway if you mirror the files.
The other escape hatch: build with webpack
Test B shows that webpack plus NODE_EXTRA_CA_CERTS works, so next build --webpack with your existing certificate setup is a legitimate stop-gap. It's the same flag I use on this site for a different reason — a plugin that only works under webpack.
I'd treat it as temporary. Next.js recommends Turbopack for production, and opting out to fix a font download means carrying a bundler choice for the wrong reason.
What not to do
Don't turn off certificate checking. NODE_TLS_REJECT_UNAUTHORIZED=0 is the answer that shows up in old threads. I didn't test it, because there's no situation where I'd recommend it — but it's a Node.js setting, so there's no reason to expect it to reach Turbopack's Rust downloader any more than NODE_EXTRA_CA_CERTS did. Where it does apply, it switches off certificate verification for every request that Node process makes, and a build process holding your deploy credentials is exactly where you don't want that.
Triage order
- Run
next --version. 16.1 or earlier and 16.2 or later have different fixes. - Check the error mentions TLS or "establishing a connection". If it times out or can't resolve the host, it's a proxy-routing problem — set
HTTPS_PROXY. - On 16.1 or earlier: set
experimental.turbopackUseSystemTlsCerts: true. On a server without the root installed, also setSSL_CERT_FILEto your company.pem. - On 16.2 or later: remove the old option and make sure the company root is in the OS trust store. Environment variables won't substitute.
- Stuck either way: self-host the font, or build with
--webpackas a stop-gap.
Key takeaways
- Under Turbopack, next/font downloads Google Fonts in Rust, not Node — so NODE_EXTRA_CA_CERTS has no effect. The same setting works under webpack.
- On Next.js 16.1 and earlier, set experimental.turbopackUseSystemTlsCerts (or NEXT_TURBOPACK_EXPERIMENTAL_USE_SYSTEM_TLS_CERTS=1). With it on, SSL_CERT_FILE also works; without it, SSL_CERT_FILE is ignored.
- From Next.js 16.2, Turbopack uses the OS certificate store by default and the option was removed. Leaving it in the config only triggers an 'Unrecognized key' warning.
- On 16.3.6, no environment variable got past an untrusted proxy certificate. The company root has to be in the system trust store.
- Self-hosting the font with next/font/local, or the geist npm package, removes the network fetch entirely and works on every version.
Frequently asked questions
Why doesn't NODE_EXTRA_CA_CERTS fix 'Failed to fetch' Google Fonts in Next.js?
Because under Turbopack the font request is not made by Node.js. Turbopack downloads Google Fonts with its own Rust HTTP client, which never reads Node's certificate variables. In my tests the same NODE_EXTRA_CA_CERTS setting made a webpack build pass and left a Turbopack build failing, on the same machine and proxy.
What is turbopackUseSystemTlsCerts and does it still exist?
It was an experimental Next.js option that made Turbopack trust the operating system's certificate store instead of its bundled roots, with an equivalent NEXT_TURBOPACK_EXPERIMENTAL_USE_SYSTEM_TLS_CERTS=1 environment variable. It exists in Next.js 16.1 and earlier. It was removed in 16.2, when Turbopack started using the system store by default. On 16.3.6, leaving it in your config produces an 'Unrecognized key' warning and does nothing.
How do I fix Google Fonts behind a corporate proxy on Next.js 16.2 or later?
Make sure your corporate root certificate is installed in the operating system's trust store, which Turbopack now reads by default; on managed company laptops it usually already is. Environment variables do not help: on 16.3.6, NODE_EXTRA_CA_CERTS and SSL_CERT_FILE both failed in my tests. If you can't change the trust store, self-host the font with next/font/local so the build never fetches from Google.
Does setting HTTPS_PROXY fix the Next.js Google Fonts error?
Only if the problem is that you can't reach Google at all. Turbopack honours HTTP_PROXY and HTTPS_PROXY, so the proxy setting gets the request out. It does not make Turbopack trust the proxy's certificate. In every failing test, HTTPS_PROXY was already set and the request reached the proxy; the failure was certificate trust.
The same pattern — the usual certificate variable not reaching the code that actually makes the request — is behind Claude Code's corporate-proxy SSL errors too. If you're moving a Next.js codebase onto 16 inside a locked-down network, that's the kind of work I do — see recent projects.
References
- Turbopack: Add an option to use system TLS certificates (vercel/next.js #81818)github.com · accessed 2026-10-02
- Turbopack: Update reqwest, remove experimental system TLS feature (vercel/next.js #88290)github.com · accessed 2026-10-02
- Turbopack: Use webpki-root-certs in addition to rustls-platform-verifier on Linux (vercel/next.js #88869)github.com · accessed 2026-10-02
- "Error while requesting resource" with next/font/google using next dev --turbopack (vercel/next.js #78472)github.com · accessed 2026-10-02
- Font component — Next.js docsnextjs.org · accessed 2026-10-02
Last reviewed October 2, 2026
Tahir Nazir
Senior AI Engineer & Full-Stack Lead
5+ years shipping AI-powered products — RAG pipelines, agentic workflows, and MCP tooling. Top Rated on Upwork with a 100% job success score.
More about Tahir →Keep reading
New posts land here first. Follow along by RSS, or get in touch if you are building something similar.
Related articles
Next.js 16 Turbopack webpack Config Error: Don't Silence It
Next.js 16 fails the build when it finds a webpack config, and the error suggests turbopack: {}. I tested it. The build passes — and the service worker silently disappears.TroubleshootingWeb Development10 min readClaude Code Behind a Corporate Proxy: Why NODE_EXTRA_CA_CERTS Isn't the Fix
Unable to get local issuer certificate behind Zscaler or any TLS-inspecting proxy. Claude Code already trusts your OS certificate store by default — so the usual advice fixes it for some people and not others. The variable that actually decides is CLAUDE_CODE_CERT_STORE, and whether your runtime can read the OS store at all.TroubleshootingAI Engineering11 min readClaude Code on Vertex AI: Why You Get 404s, Wrong Regions and an Opus-Sized Bill
Model not found on Google Cloud's Agent Platform is rarely one problem. A malformed region is silently ignored and falls back to us-east5, ANTHROPIC_VERTEX_PROJECT_ID overrides the project in your credentials, and a deployment with no pinned model is billed at the Opus rate.TroubleshootingAI Engineering10 min read