Orange-to-Orange (O2O) is a request that crosses two Cloudflare zones. Your proxied hostname points at a SaaS platform that also runs on Cloudflare, so your settings are applied first and the provider’s second, before the request reaches their origin.
If you run a Shopify store, a Webflow site, or any platform built on Cloudflare for SaaS, and your own domain is on Cloudflare too, you are probably in an orange to orange setup — whether or not anyone told you. It explains a class of confusing behaviour: a cache rule that does nothing, a redirect that loops, a WAF rule that fires in a dashboard you cannot see.
First, the orange cloud
In Cloudflare, a DNS record marked with the orange cloud is proxied: queries return Cloudflare anycast addresses and HTTP traffic passes through Cloudflare before it reaches an origin. A gray cloud means DNS only. O2O is simply what happens when both ends of that path are orange. If any of that is unfamiliar, start with what the orange cloud means in Cloudflare.
When O2O happens
All of the following have to be true at once:
- Your SaaS provider uses Cloudflare for SaaS and has created your hostname as a custom hostname in their zone.
- Your domain’s authoritative DNS is Cloudflare — you have your own zone.
- That zone holds a CNAME record matching the custom hostname, pointing at the target the provider gave you, and it is proxied.
- The two zones sit in different Cloudflare accounts.
| Type | Name | Target | Proxy status |
|---|---|---|---|
| CNAME | shop | customers.saasprovider.example | Proxied |
Two things that do not produce O2O: an A record pointing at the provider’s addresses (apex proxying is not CNAME-based, so it never triggers O2O), and a gray-clouded CNAME — that is an ordinary custom hostname, where only the provider’s zone has any say. O2O also refuses to chain further: traffic that has entered one custom-hostname zone will not be routed onward into another.
How the request actually travels
- A visitor resolves your hostname. Because your record is proxied, they get Cloudflare anycast addresses and connect to the nearest Cloudflare data centre.
- Your zone processes the request first. Your WAF rules, cache configuration, redirects, and Workers run here, on your plan, visible in your analytics.
- The request is handed to the provider’s zone inside Cloudflare’s network — it does not exit to the public internet and come back. On the way in, Cloudflare stamps the request with the header
cf-connecting-o2o: 1, which is how the provider (in their origin or a Worker) can tell O2O traffic apart. - The provider’s zone processes it second, applying their security and caching configuration, and then forwards it to their origin — the servers that actually render your store or site.
Which zone’s configuration wins
The governing rule from Cloudflare is short: settings on your zone override settings on the provider’s zone. In practice a request has to survive both, and each product falls into one of four buckets.
| Where it takes effect | Products |
|---|---|
| Both zones — yours first, theirs second | Access, WAF custom rules, WAF managed rules, Bot Management, Browser Integrity Check, Security Level, Waiting Room, Client-side Security (Page Shield), Image resizing, IPv6 |
| Your zone only | API Shield, Zaraz |
| Provider’s zone only | Argo Smart Routing, Load Balancing, Origin Rules — your zone can still use Argo and Load Balancing for hostnames that are not on O2O |
| Neither | Spectrum, WebSockets, Rocket Loader, China Network |
Several products work on your side but deserve care before you touch them:
- Cache. Supported, and generally discouraged for HTML. Your provider very likely caches outside Cloudflare, so caching in your zone invites stale or out-of-sync content. Caching hostnames that do not route to the provider is fine.
- Workers, Page Rules, Transform Rules, Rate Limiting. All run in your zone, and all can block or distort traffic on the O2O hostname if the rule matches it. Scope rules to hostnames you actually own end to end.
- Polish. Only optimises cached assets, so if your zone bypasses cache for provider-bound traffic there is nothing for it to optimise.
- DNS. Keep the records that make the setup work. Deleting the CNAME does not just break routing — it tells the provider you are gone, and the custom hostname moves to a removed state.
- HTTP/2 prioritization and IPv6 compatibility depend on matching settings across the two zones to behave as expected.
This summary compresses Cloudflare’s per-product table; before you rely on any single row, check the official compatibility list, which is updated as products change.
How to tell whether a hostname is on O2O
There is no zone setting or API field that reports “O2O is on” — it is per-request routing behaviour that falls out of your DNS configuration. So you check the inputs:
- Your DNS. Is the record a CNAME, pointing at a target the provider gave you, and proxied? For some providers the Cloudflare dashboard even shows their icon next to the record.
- Resolution.
dig +short shop.example.comreturns Cloudflare anycast addresses rather than the provider’s — expected, and confirms the record is proxied. - The provider’s side. If you are the SaaS provider, look for
cf-connecting-o2o: 1on inbound requests, at your origin or in a Worker. That header is set only on requests entering your zone through O2O. - Your analytics. Traffic for that hostname shows up in your own zone’s HTTP analytics, because your zone genuinely sees the request first.
What goes wrong
Certificates stop renewing after you enable Always Use HTTPS
A classic, and documented for Shopify in particular. Providers often validate certificates over HTTP-01, which requires /.well-known/acme-challenge/* to be reachable over plain HTTP. Always Use HTTPS redirects that path too, so validation fails and the certificate is never issued or renewed. Use a redirect rule that enforces HTTPS while excluding the ACME path instead.
Redirect loops or blank pages after adding a rule
Look at what your own zone applies to that hostname: a Page Rule, Transform Rule, Redirect, or Worker that matches the O2O subdomain. Your zone runs first, so a rewrite or redirect there is applied to traffic the provider expects to receive untouched.
Cache hit rate is far lower than expected
If the provider’s zone has Bot Management enabled, its __cf_bm cookie comes back in a Set-Cookie response header — and a response with Set-Cookie is not cached by default in your zone. The result is an eyeball-facing zone that caches far less than you planned.
A feature you enabled seems to do nothing
Check the bucket table above. Load Balancing, Origin Rules, Argo Smart Routing, WebSockets and Spectrum are not yours to control on an O2O hostname; that configuration belongs to the provider.
The provider cannot activate your custom hostname
If your zone is on an Enterprise plan with a zone hold enabled, activation is refused and the provider sees an error saying the hostname belongs to a held zone. Release the hold temporarily (including the subdomain option, if you are onboarding a subdomain) and retry.
Error 1014
A cross-account CNAME to another Cloudflare zone is banned unless the target owner is using Cloudflare for SaaS. If you see Error 1014, the hostname was never onboarded on the provider’s side — that is not an O2O configuration problem, it is a missing custom hostname.
FAQ
What does orange to orange mean in Cloudflare?
It describes a request that passes through two Cloudflare zones instead of one: your own proxied hostname routes into a SaaS provider’s zone that also runs on Cloudflare. Both zones are “orange”, hence orange-to-orange.
Does O2O work with an A record?
No. O2O is triggered by a proxied CNAME record that matches a custom hostname on the provider’s zone. Apex proxying, which uses A records pointing at the provider’s addresses, does not enable O2O.
Which zone’s settings win in an O2O setup?
Your zone runs first and its settings generally override the provider’s. The provider’s zone then applies its own configuration to whatever your zone forwarded, so a request has to survive both.