You push static assets to a CDN to shave milliseconds off your load times, reload the page, and your typography collapses into Times New Roman. Open DevTools, and there it is: a bright red console error blocking your .woff2 or .ttf files.
I ran into this exact headache while shifting font delivery to a StackPath edge zone. The browser treats fonts differently than images or scripts, and if your headers aren’t dialed in across both the origin and the edge, everything falls apart. Here is how to fix your origin headers, set up StackPath EdgeRules, and stop cached errors from persisting.

The CORS Font Error and Why StackPath CDN Triggers It
Browsers enforce strict cross-origin rules on font files. Unlike stylesheets or images, any font loaded via CSS @font-face demands explicit CORS headers if the hostname serving the file differs from the hostname serving the page.
When you put StackPath in front of your assets, your web page usually lives on https://example.com, but the browser fetches fonts from https://cdn.example.com. You might own both domains, but to Chrome, Safari, and Firefox, they are completely separate origins.
If StackPath returns the font without an Access-Control-Allow-Origin header, the browser kills the request right then and there:
Access to font at 'https://cdn.example.com/fonts/inter-bold.woff2' from origin 'https://example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.This failure comes down to two culprits: your origin server never sent the CORS header in the first place, or StackPath cached an early response that didn’t include it.
Inspecting the Response Headers with curl
Before tinkering with config files, check what your servers are actually returning. You need to know if the origin is failing to output the header, or if StackPath is swallowing it at the edge.
Run a quick curl request that mimics a cross-origin browser fetch:
curl -I -H "Origin: https://example.com" https://cdn.example.com/fonts/inter-bold.woff2Check the response headers. If everything is wired up properly, you will see:
HTTP/2 200
server: StackPath
access-control-allow-origin: *
access-control-allow-methods: GET, OPTIONS
vary: Origin
content-type: font/woff2If access-control-allow-origin is missing or returns a domain that doesn’t match your front end, you found your bug. If your edge is also throwing redirect loops while you diagnose headers, take a look at our walkthrough on how to fix WordPress ERR_TOO_MANY_REDIRECTS behind StackPath CDN.
Step 1: Configure CORS Headers at Your Origin Server
The cleanest fix starts at the source. If your origin web server sends valid headers, StackPath will cache those headers with the binary font files and forward them downstream.
For Nginx Origins
Open your site config (usually under /etc/nginx/sites-available/) and locate the server block serving your assets.
Add a location block targeted directly at font extensions:
location ~* .(eot|otf|ttf|woff|woff2)$ { add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, OPTIONS" always; add_header Access-Control-Allow-Headers "*" always; add_header Vary "Origin" always; expires 365d; access_log off;
}Test your syntax and reload Nginx:
sudo nginx -t && sudo systemctl reload nginxFor Apache and LiteSpeed (.htaccess)
If you run Apache or LiteSpeed, set the headers inside your root .htaccess file using mod_headers.
Drop this near the top of the file:
Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET, OPTIONS" Header set Access-Control-Allow-Headers "*" Header append Vary "Origin"
If you’re on shared hosting with LiteSpeed, check our guide on how to resolve WordPress mixed content with LiteSpeed and .htaccess to keep all asset paths securely on HTTPS.
Step 2: Configure StackPath EdgeRules for CORS Headers
If you can’t touch the origin directly—like when files live in an S3 bucket or immutable cloud storage—you can inject the Access-Control-Allow-Origin header at the edge via StackPath EdgeRules.
- Log in to the StackPath Control Portal.
- Click Sites on the left, then select your CDN site.
- Go to the EdgeRules tab.
- Click Add Rule.
Configure the rule like this:
- Rule Name: Add CORS Headers for Web Fonts
- Description: Inject CORS headers for font assets
- If:
File Extension>Matches Any>woff, woff2, ttf, otf, eot - Then: Add Action >
Add Response Header - Header Key:
Access-Control-Allow-Origin - Header Value:
*
Add a second action right below it so caches don’t get polluted:
- Action:
Add Response Header - Header Key:
Vary - Header Value:
Origin
Save the rule and drag it near the top of your rule order so lower-priority rules don’t stomp on it.
Step 3: Handle the Origin Header Forwarding & Vary: Origin Gotcha
Here is an insidious gotcha that cost me hours: cache poisoning from non-CORS requests.
Say a crawler or a direct user hits https://cdn.example.com/fonts/inter.woff2 directly. The request contains no Origin header. The origin responds with 200 OK, but because it didn’t think this was a cross-origin call, it leaves off the Access-Control-Allow-Origin header.
StackPath dutifully caches that header-less response. A few seconds later, an actual user visits https://example.com. Their browser requests the font with Origin: https://example.com, but StackPath serves the cached response—missing the CORS header. Boom: broken fonts.
You solve this by telling the edge that cached content depends on the origin request header. Make sure your origin outputs this:
Vary: OriginThe Vary: Origin header instructs StackPath to maintain separate cache entries for cross-origin and plain direct requests. If you have a custom caching tier, read our guide on how to configure Origin Shield in StackPath CDN to keep the extra cache variations from hitting your origin twice as hard.
Step 4: Purge StackPath Cache and Verify the Fix
Changing your origin config or adding EdgeRules won’t help if StackPath is still sitting on the broken, header-less font file. You have to purge it.
- In the StackPath portal, head to Sites > Your CDN Site.
- Click Purge in the top right.
- Choose Individual Files (and enter
/fonts/*or*.woff2) or hit Purge All. - Click Submit Purge.
If you automate your builds, see how to automatically purge StackPath CDN cache with GitHub Actions on every deploy.
Once purged, test the asset from your terminal while explicitly passing an Origin header:
curl -s -D - -o /dev/null -H "Origin: https://example.com" https://cdn.example.com/fonts/inter-bold.woff2Check the output:
HTTP/2 200
date: Wed, 18 Oct 2023 14:22:10 GMT
content-type: font/woff2
access-control-allow-origin: *
vary: Origin
x-cache: HITSeeing access-control-allow-origin: * paired with x-cache: HIT means StackPath is caching the file properly and passing the necessary permissions down to the browser.
Gotcha: When Fonts Load on First Hit But Fail on Hard Reload
Ever have fonts render fine on first view, but immediately break when you check “Disable cache” in DevTools or hit Ctrl+F5?
This usually happens when an asset gets requested twice through different mechanisms. A common culprit is a tag that forgets the cross-origin attribute:
Without the attribute, the browser preloads the font anonymously without CORS credentials. A moment later, your CSS file requests the same font with CORS credentials. The browser detects conflicting cache rules and refuses to use the file.
Fix it by explicitly adding crossorigin="anonymous" to your preload link:
Frequently Asked Questions
Can I set Access-Control-Allow-Origin to my specific domain instead of an asterisk (*)?
Yes. If you want to stop other sites from hotlinking your fonts, replace * with your exact root URL, like https://example.com. Just remember that if you have multiple subdomains (like blog.example.com and app.example.com), the wildcard * is much simpler unless your origin server dynamically mirrors the incoming Origin header.
Does setting Access-Control-Allow-Origin to * create a security vulnerability for fonts?
No. Fonts don’t carry cookies, sessions, or user data. Wildcarding public fonts is standard practice across the web—Google Fonts and Typekit do the exact same thing.
Why does StackPath strip my origin headers?
StackPath doesn’t strip CORS headers on purpose. This usually happens if an EdgeRule is accidentally overwriting headers, or if your origin sends Cache-Control: private or no-store. If your origin tells the CDN a file is uncacheable, edge proxy behavior gets erratic. Always make sure your font assets return Cache-Control: public, max-age=31536000.
Do I need to configure CORS for SVG icons too?
If you load SVGs as an icon font via @font-face or pull them with fetch() / XMLHttpRequest from the CDN domain, yes. If you’re just embedding them in regular tags, CORS headers aren’t needed.
Next Steps
Now that your typography renders without console warnings, make sure your CDN isn’t inadvertently caching personalized or dynamic data. Check out how to bypass StackPath CDN cache for logged-in WordPress users to prevent auth leaks on user-specific pages.

