OTF file gives cf-cache-status: DYNAMIC

I’m using “Cache everything” setting and am correctly seeing HIT in the headers for HTML and images.

However, there’s one OTF font that gives a status of DYNAMIC and I’m trying to figure out why.

My origin server .htaccess has:

   <filesMatch ".(gif|ico|jpg|jpeg|mp4|png|svg|webp|otf)$">
        Header set Cache-Control "max-age=31536000, public"

The response header for the OTF file has the following, which is as it should be:

  cache-control: max-age=31536000, public

However, it never seems to HIT.

Here’s an example page: 19. Histograms with Matplotlib | Numerical Programming


I believe Cloudflare does not follow the Cache-Control header. It seems like you will need to create a page rule to make it cache filetypes other than the ones listed here. At the bottom of that page you can also see what all the CF-Cache-Status values mean.

But OTF is listed there and therefore should be cached. But it depends on the settings.

@murraybourne would you mind changing the content-type from:

to: font/otf, so it matches your preload tag: <link rel="preload" href="/includes/cssjs/fonts/FluxRegular.otf" as="font" type="font/otf" crossorigin>

To do so, you can check this Gist: .htaccess · GitHub and take the necessary parts you need and include it in your .htaccess

Then clear all cache and try again.

P.S.: please consider converting your OTF font to WOFF2 (and ofc all other modern formats) and provide more modern formats to speed up your page.

This seems inconsistent when using “cache everything” - sometimes Cloudflare seems to set its own max-age, ignoring any .htaccess settings. But I just changed my .htaccess to say max-age=31536001 (i.e. changing it to “1” at the end), and that’s what’s showing up in the headers. So it seems it is recognising it in this case.

@M4rt1n: Curiously, I don’t see that content-type line in my Response Headers.

Seemed like the best approach was to take your final advice and I converted the font to woff2 (and added that extension to my .htaccess).

However, it’s still showing DYNAMIC and is the slowest loading thing on most pages.

Could you please post the full response header your server is creating?
Also please share your PageRules so we can have a look at and see if there is something that causes this.

On your new WOFF2 file I dont see any content-type at all… something is getting done here somewhere, but since I don’t know your origin IP I can’t test against your origin.

Thank you.

Your response made me wonder whether the “AddType” was missing, and sure enough, it was and I added it.

So I’m now seeing the content type, but also still seeing DYNAMIC.

The full response I’m getting is:

h3=":443"; ma=86400, h3-29=":443"; ma=86400
max-age=31536001, public
Thu, 28 Apr 2022 07:02:01 GMT
max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Mon, 25 Apr 2022 23:28:19 GMT
max-age=63072000; includeSubdomains
1; mode=block

As for page rules, I’ve got the first 2 rules (for admin directories ,etc) that are “Cache Level: Bypass”, followed by the 3rd rule:

Cache Level: Cache Everything

Nothing specifically about WOFF2, or any other font that would affect anything.

The origin server is at

Thats a Cloudflare IP.

Would you mind posting all 3 PageRules?

I just downloaded the font, hosted it on my server and checked. It is getting cached. #SEE So there must be something on your side, or within your Cloudflare configuration. Also your content-type is always different from mine. Even tho I think this is not the problem here our content-types:

Mine: content-type: font/woff2
Yours: content-type: application/x-font-woff2

Thats not the the response your server is creating, thats the response Cloudflare is creating. I would like to see the header of your server before it is hitting Cloudflare.

The output of this command will give this information (replace the variable including the <>):

curl --dump-header - -o /dev/null https://python-course.eu/includes/cssjs/fonts/FluxRegular.woff2 --connect-to ::<INSERT-ORIGIN-HERE>

1 Like

@michael: Thanks.

@M4rt1n: Here are the page rules:

python-course.eu/my-admin-directory-1* Cache Level: Bypass Enabled
python-course.eu/my-admin-directory-2* Cache Level: Bypass Enabled
python-course.eu/* Cache Level: Cache Everything

Here’s the result of the curl:

Date: Thu, 28 Apr 2022 23:11:44 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/7.1.33
Strict-Transport-Security: max-age=63072000; includeSubdomains
Last-Modified: Mon, 25 Apr 2022 23:28:19 GMT
ETag: "2560-5dd82ee6a8ac0"
Accept-Ranges: bytes
Content-Length: 9568
Vary: Accept-Encoding
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: max-age=31536001, public
Content-Type: application/x-font-woff2

The above shows the Content-Type as per my “AddType” directive.

So there must be something on your side

I wondered if it was just my browser or local setup too, but checks on GTMetrix and WebPageTest show the same behaviour.

Thanks for pursuing this.

Files with the .woff2 extension should be cached by default. The Cache Everything page rule would make it cacheable anyway. So there is not reason for DYNAMIC!

Do you have Development Mode enabled?

The correct (as per RFC8081) type is font/woff2 as @M4rt1n said above. While it should make no difference, can you update your config to the standard MIME type and see if it does anything. Similarly, your otf fonts should have MIME type font/otf.

1 Like

Yep - that’s why I’m here :slight_smile: (Actually, it’s showing DYNAMIC, not BYPASS.)

Everything else is caching just fine.


Changed. (Proves you can’t believe everything you read on the Net…)

No OTF fonts on the site now - just this one troublesome WOFF2.


I figured it. The font was in one of the “admin” directories so it was just doing what the page rule told it to do - not cache it.

It now successfully gives me a HIT.

So sorry to have wasted your time.


How you figured it out? In which file the page rule was there? I am also getting same issue.

The OP had the following page rules. The uncached file was being matched by one of the first two rules. Only one Page Rule will ever match, and it is the first Page Rule in the list when you read the rules from the top down.