Security response headers from origin not passed by Cloudflare

Hello Cloudflare Team and Community,

I’ve applied security headers on origin webserver (nginx) to be passed on responses, listed below, but Cloudflare doesn’t seem to pass them, even after purging all cache multiple times.

The headers are on the domain (Pro plan):

Strict-Transport-Security “max-age=31536000; includeSubDomains; preload”;
X-Content-Type-Options nosniff;
X-Frame-Options “SAMEORIGIN”;
Content-Security-Policy “frame-ancestors ‘self’;”;
X-XSS-Protection “1; mode=block”;

Even already paying for a Pro plan, I do not want to pay for Workers to add the headers since the site receive dozens of millions of access per month, which would generate extra costs, unnecessarily.

Also, it’s not nice to pay for a feature already 100% done and solved on my own server, and it would be interesting if Cloudflare could “pass” those headers as well, already defined on origin.


If someone test the domain, the HSTS and X-Content-Type-Options are present only because there are options to enable them directly on Cloudflare.

They are not being passed from the origin and that is the reason why all our other security headers are wrongly missing.

I see some of the headers coming through. Can you run the following command which will show your origin response bypassing Cloudflare, and share the result:

curl --resolve<origin IP address> -o /dev/null --dump-header -

1 Like

Thanks, Michael. I’m posting right now.

It seems the headers are not present, which is strange:

server: nginx/1.19.2
date: Sat, 13 Feb 2021 13:00:19 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
cf-edge-cache: cache,platform=wordpress
link:; rel=“
link:; rel=“alternate”; type=“application/json”
x-fastcgi-cache: HIT

I will reset the fastcgi cache to see if this is the root cause.

Make sure you use the Origin IP address. This looks like the request still came through Cloudflare.

1 Like

Your original instruction is correct, and I’m replacing <origin IP address> with the origin IP, but the response is still the same, with cf-edge-cache: cache,platform=wordpress

I even tried adding both port 80 and 443, as well as www and non-www, with:

curl --resolve<origin IP address> --resolve<origin IP address> --resolve<origin IP address> --resolve<origin IP address> -o /dev/null --dump-header -

(replacing <origin IP address> with my server’s dedicated IP)

But the result is still the same…

I tested inside the dedicated server from, and the problem is that the dedicated server itself is passing the Cloudflare response. How can this be even possible?

Even forcing the curl request with the --resolve parameter inside the dedicated server. I’ve never seen this before. :slightly_frowning_face:

This site is using Wordpress, the Cloudflare Wordpress plugin and APO, but technically it would not be able to remove headers added from Nginx, right?

OK. Ran my own test with an OVH address that has a Let’s Encrypt cert for your hostname. Not sure how that cf-edge-cache header is getting in there, but that’s a separate investigation for you.

The origin is not responding with the headers you are setting, so Cloudflare cannot pass them through. Investigation of what is happening in your Nginx/Wordpress setup is left as an exercise for the user!

1 Like

Thanks, Michael! I will investigate!

Cause discovered! The defined headers weren’t being applied for the reasons explained here:

One is that nginx only processes the last add_header it spots down a tree. So if you have an add_header in the server context, then another in the location nested context, it will only process the add_header directive inside the location context. Only the deepest context.

and on official Ngin docs:

There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.

Now I identified this on my config and applied the necessary changes. Everything is correct, now.

1 Like

Any idea where the cf-edge-cache header is coming from? Are you proxying against another Cloudflare host?

You can also configure the HSTS and x-content-type-options Headers using the HSTS feature on the Cloudflare dashboard.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.