Cloudflare proxy for AWS API Gateway

I’m trying to set up a Cloudflare proxy for AWS API Gateway but I’m struggling with the configuration.

I also generated a Cloudflare origin certificate and imported it into AWS Certificate Manager (adding the Cloudflare CA certificate to the chain), and then associated it to a Custom Domain Name in API Gateway, added the mapping and updated the CNAME record in Cloudflare DNS to point my subdomain to the new API Gateway endpoint. Unfortunately this didn’t work, and I got an error when I tried calling my API. This seems to be due to the fact that AWS no longer accepts Cloudflare’s self-signed certificates.

So I followed the advice from user ‘Judge’ in this thread: Can't get certificate chain

I replaced the Cloudflare origin certificate by a certificate created through ACM and updated the config in API Gateway. This did work as long as I configured the CNAME in Cloudflare as ‘DNS-only’ (even in SSL(Strict) mode). But when I turn on the Cloudflare proxy I get an error as described here: To proxy or not to proxy.

Any help would be appreciated.

1 Like

Same exact issue. Tracking other replies to @user2330 post too. Thanks.

I’ve been thinking about this one for a bit. I haven’t tried it with Cloudflare, but have some experience with proxying API Gateway through other means. To start with, I would like to understand what the DNS setup looks like here. Are we talking about something like this? This is a question to both of you.

Cloudflare DNS:
Name: custom-domain
Proxy status: Proxied

AWS Management Console, API Gateway:
Custom domain name

I’m not too worried about certificates and such right now. At this point I want to establish what the DNS configuration looks like - is it straightforward like in the example above or are we talking about a more elaborate setup?

Hi there, thanks for your reply.

Yes that’s exactly the configuration that I tried to make work (but it fails as soon as I turn the Cloudflare proxy on for the CNAME in question).

One thing to note is that the ‘example’ String is the API Gateway domain name provided from the ‘Custom domain names’ tab in AWS API Gateway (ie the second character is typically a dash, eg d-dfmsu4xxxx).

If you have an idea how to make this work I would be really grateful.

Great, then we have established that.

How does it fail exactly right now? Is there any error message that might provide a clue?

Sounds good, that’s what I was expecting.

I’ve just reproduced the issue. I get a 521 error on the preflight request for whatever API call I try to make.

The error I get is “Access to XMLHttpRequest at ‘’ from origin ‘’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”

Behind the scenes the API is created using the Serverless framework and the corresponding AWS Lambda function does return the “Access-Control-Allow-Origin” header. It works fine so long as the Cloudflare Proxy isn’t enabled.

Ideally I would like to avoid the preflight request altogether but I’m not sure it’s possible since the website and the api are on different subdomains. In any case the preflight requests should not be failing.

NB as you can guess from my previous post I’m testing using a browser. It’s also possible to call the API via curl or a tool like Postman but it’s not straightforward because the API requires authentication using a JWT token. Maybe that’s what’s causing the issue.

I’m experimenting a bit here and based on what I’ve seen so far it’s not necessarily an issue with the preflight request. Not sure yet, but in the meantime you can check the “Encryption mode” under “SSL/TLS” → “Overview” in the Cloudflare dashboard.

I ran into that 521 error with the mode set to Flexible (plain HTTP between Cloudflare and API Gateway when HTTPS is expected).

After switching to Full (HTTPS between Cloudflare and API Gateway, not so strict cert validation) instead, my requests went through just fine. Note that I haven’t been able to test with preflight requests yet due to unrelated issues with my test setup.

What you want is Full (Strict) which has a more strict cert validation, but Full is enough for a quick test.

DNS record was proxied during this test.

I’m thrilled to say that this worked! I actually had the SSL config on Flexible by default but I had a page rule that set SSL to Full (Strict) for This was because my @ CNAME is pointing to an S3 bucket with web hosting, and S3 doesn’t support https.

This should have worked except my page rule pattern should have been*

After changing this my api CNAME now points to my AWS API Gateway custom domain endpoint with Cloudflare Proxy enabled and it works!

Many thanks for your post, I don’t think I would have figured it out otherwise.

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