Have Cloudflare Ignore Cache-Control Header
Hello π
I am using Vercel and a rewrite in vercel.json to make my /blog subpath reverse proxy to a domain fronted by cloudflare.
However from the logs on the blog side, I can see that Cache-Control is set to max-age=0 which is causing all my request to the /blog path to be misses.
How can I make Cloudflare ignore the max-age=0 header? π€
126 Replies
Cloudflare Docs
CDN-Cache-Control Β· Cloudflare Cache (CDN) docs
CDN-Cache-Control is a response header field set on the origin to separately control the behavior of CDN caches from other intermediaries that might β¦
Thank you for taking time to answer @HardlyWorkin' !
I have done that and added those to my origin but still getting MISS - I see from logging my incoming headers that I'm getting Cache-Control: max-age=0 - does that affect Cloudflare-CDN-Cache-Control directives? π€
You can observe the behaviour here:
1. Reverse Proxied URL from Vercel: https://outlater.com/blog
2. Target URL of reverse proxy: https://testdocs.assistflare.com (origin)
Huh, just tested, and I'm getting a 502 Gateway error
ahh, can you try again
I was messing around testing some different things
@HardlyWorkin'
Wait, you are double-layering Cloudflare on top of Vercel?
Nope, the origin is on a VPS
The reverse proxied URL (outlater.com) is on Vercel but it's just that - a reverse proxy
Why are both serving Cloudflare headers then?
This is what I have in the app on vercel to do the rewrite:
"rewrites": [
{
"source": "/blog",
"destination": "https://testdocs.assistflare.com"
}
]
I suspect the rewrite from Vercel is pulling the headers from the origin and displaying those - which is why you see "X-Powered-By "AssistFlare" in the response headers from outler.com/blog
This header is actually from my origin:
Doesn't Vercel overwrite
server
though?I'm not sure I understand what you mean by server? π€
Oh wait
nvm
The server header shows who is serving the request
It's been driving me nuts for 3 days!
Though funnily enough, Vercel also uses Cloudflare
So it is double-stacked, just in a different way
Yeah, I am starting to think something funny is happening
So there's no way to have the Vercel <-> Cloudflare reverse-proxy actually hit the cache on Cloudflare - because right now my origin gets hit everytime.
Funny thing is I tried to implement the same reverse proxy from another VPS to the same URL of testdocs.assistflare.com and it works flawlessly and shows HIT on the reverse-proxied URL response headers.
Wait, so just to confirm, you have proxy on your origin, correct?
I have Cloudflare on my origin. The reverse-proxy is implemented on Vercel using rewrites on vercel.json
This is just a test I did to isolate this to Vercel
Something very weird is going on. I've done about 20 requests to your origin, and all have the exact same Ray-ID...
Which shouldn't happen
interesting!
What does this mean? π€
This is my full Vercel.json:
{
"headers": [
{
"source": "/blog",
"headers": [
{
"key": "Vercel-CDN-Cache-Control",
"value": "s-maxage=0"
}
]
}
],
"rewrites": [
{
"source": "/blog",
"destination": "https://testdocs.assistflare.com"
}
]
}
The initial headers block is supposedly to disable the Vercel CDN...from the docs: https://vercel.com/docs/edge-network/frequently-asked-questions#how-do-i-use-cloudflare-over-the-vercel-edge-network-disable-it
Edge Network Frequently Asked Questions (FAQ)
A list of frequently asked questions and answers related to the Vercel Edge Network.
That's only if you use Cloudflare on top, which you aren't doing
You are using Cloudflare below
Ahh, this is because I did not properly disable vercel edge cache - s-maxage in the above was actually = 5; I just redeployed to set it to 0
The ray-ids should now update every request - but MISS is still always happening
Yes, which I found very strange as well. The reverse-proxy is picking up all the headers from Vercel all the way down to the origin and displaying those.
Vercel -> Cloudflare -> origin (VPS)
Any thoughts on what I could try next? @HardlyWorkin'?
Youβre my only hope right now π
Not sure if it helps, but the only way I could get the reverse-proxy to show anything other than MISS is if I bypass the cache using a Cache rule in Cloudflare, which then shows DYNAMIC:
What if you set the
max-age
to 2 hours?Let me try that right now π
You want this done one the Cache Rule or on my origin itself?
On your origin first
Done, still MISS:
Reflects on https://outlater.com/blog
outlater.com/blog - Knowledge Base
outlater.com/blog - Knowledge Base
I'm getting half hit/miss, so it looks like it is working(slowly)
How are you checking that? DevTools? π€
I'm getting only misses:
Just ran this on my end - zero HIT, all MISS
Do I have to give it some time? π€
I wouldn't think so? I see the changes in your cache-control, so it should be active now...
interesting - I just ran the curl command on the origin VPS - and I get HITs and misses...
on my laptop iit's all miss
what is happening lol
This is super interesting behavior
So, my server is in Paris and uses the CDG node and it's getting 80% HIT, 20% miss. My laptop is routing via SIN & MAD mostly and those are 100% MISS all the time
Is this a cache of those nodes not caching the requests or something?
Shoud this be happening even if tiered cached is enabled? π€
@HardlyWorkin' - this is just an issue because of my location if I understand correctly?
I'm tripping here lol, why does it work from my server (Paris) but not from my laptop (Mauritius). I thought no matter what, the request is reverse-proxied by Vercel, so that shoudln't matter. Unless it's the way Vercel & Cloudflare are double stacked? π€
My brain hurts, I would appreciate some answers π
Not sure tbh. I'm still getting intermittent hits, so it isn't 100% working for me either...
yup, same here, intermitttent hit via CDG. I changed to max-age=5 secs a few minutes back to see if I get no HITs at all from CDG, but still working but with intermittent HITs.
if it's being weird, why not use a cache rule on that specific path to force it?
I have one, @Chaika - specifically hard-coded for the domain:
I would go just a bit further and pick
Ignore cache-control header and use this TTL
, potentially overriding just for that pathI did that as well, set it for Edge TTL = 2 hours, still getting MISS from my end. @Chaika
The only way I got anything other than MISS was if I set the rule to "Bypass Cache" and then I started getting DYNAMIC
yea dynamic isn't what you want, that's no chance to cache at all lol
miss means it thinks it could have cached it but, well, missed
I would try disabling Tiered Caching next. If you're using Vercel which is Anycast behind CF it could be confusing it
yes, but lol I wanted to see if there's an effect on the request. Otherwise it's MISS and I MISS seeing HITs π
you don't have any other cache rules or page rules which could be messing with cache, right? No Cache Reserve enabled, Workers running on that path, etc?
I just did that as well some 10 mins back, purged cache and still MISS...
Itβs in front though?
No page rules, only 1 cache rule which I screenshotted above
Vercel -> CF
Not the other way around
oh, wait, he doesn't have proxy on at all
@HardlyWorkin' is right, it's Vercel (reverse proxies) -> CF -> origin (VPS, Paris)
I do, the origin URL is https://testdocs.assistflare.com
outlater.com/blog - Knowledge Base
outlater.com/blog - Knowledge Base
ahh and the zone you're modifying is the one its fetching/assistflare right?
Yes - exactly
and there is cache on there
Yes, there is π
If Vercel's CF is in front, it's going to replace the cf-cache-status with its own
Really, it also has X-Vercel-Cache in there among the headers:
Vercel doesnβt actually serve CF headers, afaik
Because all requests run through AWS first
Or smthn
Are you sure it replaces? π€
I feel Vercel is just repeating everything from origin and CF
@Chaika
If it's going through the full cdn, it would replace
Vercel is special, afaik
So they do their own thing
vercel is very special
Very special, I agree. Mind-numbingly special...
The point still remains, even if it's replacing the CF-Cache-Status header, my origin is still reached for each request
I know the default cache key has a few interesting elements such
Origin header sent by client (for CORS support).
x-http-method-override, x-http-method, and x-method-override headers.
x-forwarded-host, x-host, x-forwarded-scheme, x-original-url, x-rewrite-url, and forwarded headers.
possible the requests from Vercel and requests direct are being fragmented into separate cache keys. Also possible if you're using their Edge Functions which run on CF Workers that they do the outbound fetch in a specific way
Not using Edge functions in any way, just a simple rewrite in vercel.json:
{
"headers": [
{
"source": "/blog",
"headers": [
{
"key": "Vercel-CDN-Cache-Control",
"value": "s-maxage=0"
}
]
}
],
"rewrites": [
{
"source": "/blog",
"destination": "https://testdocs.assistflare.com"
}
]
}
Do those run on Edge?
Not sure, no idea - it's just deployed to Vercel's platform and they do their special things...
hmm, why are you not using Vercel's cache control there?
or rather, why are you forcing that to 0?
From the docs, it disables Vercel's Edge CDN...https://vercel.com/docs/edge-network/frequently-asked-questions#how-do-i-use-cloudflare-over-the-vercel-edge-network-disable-it
Edge Network Frequently Asked Questions (FAQ)
A list of frequently asked questions and answers related to the Vercel Edge Network.
but you're not using Cloudflare in front of Vercel
I was doing some testing. If Vercel's caching is enabled, that's a whole different can of worms
is Vercel's CDN, not just Cloudflare itself? Sorry, not too familiar with the platform other then it's a lot of CF whitelabelled
This header: Vercel-CDN-Cache-Control
Modifidies only the behaviour of the Vercel CDN, not cloudflare...this vercel.json is for the reverse proxy app which is deployed on vercel which reverse proxies to my next.js app hosted on a VPS on my server
@Chaika - for more clarity for you:
https://outlater.com/blog - is a Next.js app which reverse-proxies the /blog path to https://testdocs.assistflare.com which is another next.js app hosted on my VPS. testdocs.assistflare.com is on Cloudflare. outlater.com is on vercel.
outlater.com/blog - Knowledge Base
outlater.com/blog - Knowledge Base
outlater.com/blog - Knowledge Base
outlater.com/blog - Knowledge Base
This is applied on Vercel on the app hosted at outlater.com:
{
"headers": [
{
"source": "/blog",
"headers": [
{
"key": "Vercel-CDN-Cache-Control",
"value": "s-maxage=0"
}
]
}
],
"rewrites": [
{
"source": "/blog",
"destination": "https://testdocs.assistflare.com"
}
]
}
yea but outlater.com is on Vercel, and Vercel CDN is just Cloudflare as far as I know. I believe their instructions there are just for if you were running Cloudflare in front of Vercel, so that Vercel wouldn't double cache
makes sense? π¬
ahh gotcha,
I could remove it, but didn't make a different AFAIK
let me do that straight away.
I would try changing that to ~10s or so, or removing it yea
why not cache on vercel anyway though? It sounds like otherwise you'd be having Vercel fetch CF everytime wasting vercel requests/another hop
DNS over Discord: A records
outlater.com A @1.1.1.1 +noall +answer +short
diggy diggy hole
When I remove that, X-Vercel-Cache goes away, I think then no caching happens on Vercel side either way.
These are not super under my control, it's clients reverse proxying to blog they create on AssistFlare π
Isn't it some kind of cache on Amazon? If
outlater.com
is routed to AWS, then it would be kind of dumb to backhaul into CF just to pull from cacheI want to keep control on my end though because Vercel does not support stale-if-error as well
what a weird mess lol, I suppose that header being missing might be a good thing
what plan is assistflare.com on btw?
free plan
You'd need Biz or Ent for less then 1h caching
I actually replicated this issue for my actual blogging platform: stomod.com
both are on the same server
also through Vercel?
yup, same config same behaviour
Removed the Vercel-CDN-Cache-Control and deployment is live, still MISS
I think which still bugs me if why would it show HIT when I do
for i in
seq 1 20; do curl -sS -D - https://outlater.com/blog -o /dev/null; done
on my origin server vs laptop where it's all MISS π€it works on origin but not lappy? What's the cf-ray? It'll tell you the airport code at the end
CDG
My server is in Paris, so CDG is the node
From my laptop, since I'm in Mauritius, it's either SIN or MAD
This is from my laptop:
hmm for me I'm getting 502's from it right now
my bad, I accidentally stopped the app on my end, should be back up now
I also just increased to max-age=7200 to see if intermittent MISS are gone from my server curl...
So to recap, current config I am running now:
1. Tiered cache = disabled
2. 1 Cache Rule, which is set to "Use cache-control header if present, bypass cache if not"
3. Headers on origin server are:
Cache-Control "public, max-age=7200, stale-while-revalidate=2592000, stale-if-error=2592000"
Cloudflare-CDN-Cache-Control "public, max-age=7200, stale-while-revalidate=2592000, stale-if-error=2592000"
4. vercel.json rewrite is:
{
"rewrites": [
{
"source": "/blog",
"destination": "https://testdocs.assistflare.com"
}
]
}
5. Curling outlater.com/blog on my laptop (SIN/MAD) give MISS 100% of the time. Curling the same URL from my origin server (CDG) gives HITS with intermittent MISS
6. I have no idea what's what anymore π
hmm I was going to say CF Employees can trace things through and it'd be helpful but they can't really in this case since it's not direct
could you log the exact requests your origin at the end gets, all request headers?
Wait this is not the right one
Would need a few requests worth, like 5 or so
let me pull a fresh one
Here you go, from the curl requests from my laptop, all MISS:
This is from my origin server, with HITs with intermittent MISS:
That
'forwarded' => {
name: 'forwarded',
value: 'for=51.159.166.190;host=outlater.com;proto=https;sig=0QmVhcmVyIGUyODk5NjQyODZiOTIxMGYxMTMzNWE3YjdlYmFmMTU2NjE5MDgwZmQ1NGY0OTllMWY3ZjU0OTZjOTcwNWQzODE=;exp=1711554575'
},
is its own standalone header right?
Cloudflare says that is part of its Cache Key:
x-forwarded-host, x-host, x-forwarded-scheme, x-original-url, x-rewrite-url, and forwarded headers.
https://developers.cloudflare.com/cache/how-to/cache-keys/what do you mean standalone header? π€
I mean, it is just a header being send as a request header right?
It was displayed different then the rest
I guess that's just how it got dumped
oh nvm its not, it's just too long to be on one line, opps
yup, it's just a request header, displayed differently because it's longer than the rest
well eitherway that seems to be your issue. It's differing on each request, everytime it differs it's a different cache key/sharding cache too much
idk what that signature or exp part is
Is that your origin ip? at scaleway?
51.159.166.190
yup
that's the server IP
I wonder what is adding
forwarded
I guess Vercel?99.9% sure it's vercel
let me get the logs when accessing testdocs.assistflare.com directly
and share here
oh yea good idea
just want to make sure it's not being added by anything else
This is it, no forwarded on this one:
You could try adding a transform rule modify request header rule to drop it:
under transform rules -> modify request headers -> new
opps, make header name lowercase
let me do that!
@Chaika - it works!
I'm getting HIT on outlater.com/blog!
Thank you so much!!!
π
lol I hate vercel
no problem, at least we figured it out
nice that you had request logs, sometimes those are really annoying to get
I am going to write a rant tweet after this and tag Guillermo Rauch
π
You were amazing! I would love to get you a coffee or something for helping out! Let me know if there's anyway to do that :p
I never knew how cache keys are formed on CF side, good to know this! π
Forwarded is a standard header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded but I'm not sure the sig part is/what exactly Vercel is doing with it
yea I kinda had a feeling. Miss means that it did try but just missed. Dynamic would be if it wasn't trying at all
does dropping it have any effect on how thing will work on the app level? π€
well good to know for the future eitherway, Vercel's rewrites mess with cache
This header is used for debugging, statistics, and generating location-dependent content. By design, it exposes privacy sensitive information, such as the IP address of the client. Therefore, the user's privacy must be kept in mind when deploying this header.not unless you were reading it but there's lots of other headers to get that info from, like X-Forwarded-For and such If you wanted, you could make your transform rule rewrite it to a different header name and then drop it after, but probably not needed
ahh, then we should be good - this was a crazy ride! Thank you so much once again Chaika! I have been struggling with this for 3 days! You and @HardlyWorkin' both π€
Have a nice day/evening whereever you are! I'm so grateful to you guys! π