Cloudflare’s DNS UI has a small orange-cloud icon next to every A / AAAA / CNAME record. Orange means “proxied through Cloudflare’s edge”; grey means “DNS-only, traffic goes direct to your origin”. Most users do not realize how much that one icon changes — it is not just a CDN toggle. Orange-cloud rewrites the SSL chain, hides the origin IP, inspects every request through Cloudflare’s WAF, and uses Cloudflare’s own IPs in DNS responses. Flipping it from orange to grey (or vice versa) is the single most common cause of “I changed nothing and it broke” in any Cloudflare-fronted stack. Symptoms range from sudden SSL warnings, to WebSocket disconnects, to your SSL cert provider refusing to issue, to your origin getting hammered by direct attacks the next day.
Common causes
Each scenario below is “flipped the wrong cloud” — knowing which scenario you’re in tells you which way to flip.
1. Origin SSL cert provider needs grey cloud during issuance
Let’s Encrypt’s HTTP-01 challenge hits http://yourdomain.com/.well-known/acme-challenge/.... If the cloud is orange, Cloudflare’s edge answers first — it serves its own response, not your origin’s challenge file. The CA cannot validate and the cert issuance hangs in pending.
How to spot it: Your platform (Vercel, Render, Fly, custom origin) shows “SSL pending” for hours. The Cloudflare DNS UI shows orange next to the A record for the apex or www.
2. WebSocket connection dropped at edge
Cloudflare’s free and Pro plans support WebSockets via the orange proxy, but with a 100-second idle timeout and HTTP-only on most plans. If your app uses long-lived sockets (Phoenix Channels, Socket.IO, real-time collaboration), connections die every 100s on orange.
How to spot it: Sockets reconnect every ~100s, errors say 1006 or going away. Direct connection to origin works fine for hours.
3. apex CNAME flattening hits Cloudflare’s edge unexpectedly
You set yourdomain.com as a CNAME to app.platform.com. DNS doesn’t natively allow CNAME at apex, so Cloudflare “flattens” it — but only when the cloud is orange. With grey, the CNAME returns as-is and many resolvers reject the apex query.
How to spot it: Grey cloud + apex CNAME = intermittent NXDOMAIN at apex. Orange cloud = works, but Cloudflare IPs are returned, not the platform’s.
4. Origin protected only because Cloudflare hides the IP
You enabled orange cloud weeks ago. Then you toggled to grey for some reason (cert issuance, debugging, vendor instruction). The DNS now returns your origin IP directly. Attackers who previously could not find your origin now hammer it.
How to spot it: Origin server’s load spikes, log shows direct hits not via Cloudflare’s IP ranges (visible in cf-connecting-ip header absence).
5. SSL Full vs Flexible mismatch surfacing on toggle
When orange, Cloudflare’s SSL mode (Flexible / Full / Full-Strict) determines how it talks to your origin. If your origin redirects HTTP to HTTPS and Cloudflare’s mode is Flexible, you get an infinite redirect loop. If your origin’s cert is self-signed and you’re on Full-Strict, you get 526.
How to spot it: Errors ERR_TOO_MANY_REDIRECTS (Flexible+origin-redirect), 526 Invalid SSL certificate (Full-Strict+self-signed origin).
6. Page Rules / Workers only run when orange
Page Rules, Workers, Transform Rules, Cache Rules — none of them execute for grey-cloud records. If you flip grey for “DNS test” and forget, your edge logic is silently disabled.
How to spot it: Headers your Worker injects are missing. Cache hit rate at Cloudflare drops to zero. cf-ray header is absent in browser DevTools.
Before you start
- Open the Cloudflare DNS panel and note the current cloud color of each record (apex, www, any subdomain in scope).
- Check the SSL/TLS mode in Cloudflare dashboard: Flexible / Full / Full-Strict / Strict-Origin.
- Identify which platform owns each subdomain (origin server, Vercel, Fly, etc.) — different platforms need different cloud states.
- Have your origin’s direct IP handy in case you need to test with
curl --resolve.
Information to collect
- Output of
dig yourdomain.com +short— Cloudflare IPs (usually 104.x or 172.67.x) vs origin IP. - Output of
curl -I https://yourdomain.com— look forcf-ray:,server: cloudflare. - SSL mode setting from Cloudflare SSL/TLS tab.
- Screenshot of the DNS record list with cloud icons visible.
- Any recent change log: who toggled, when, why.
Step-by-step fix
Apply the right pattern for your situation.
Step 1: Decide the correct end state per record
Quick rules:
- Apex A records pointing at platform IPs (Vercel, Netlify): orange OK once cert issued, but the platform may NOT support being behind Cloudflare’s proxy. Check platform docs. Vercel and Netlify generally prefer grey.
- CNAME at apex pointing to
<platform>.com: orange enables flattening, but origin platform may reject Cloudflare IPs in the Host header. Test with platform’s specific guidance. - Origin servers (your own VM/container): orange recommended for DDoS + caching, set SSL mode to Full-Strict with a valid origin cert.
- Mail records (MX, SPF, DKIM): NEVER proxy. Mail servers do not speak HTTP. Always grey. (Cloudflare won’t let you orange MX anyway.)
- WebSocket-heavy subdomains: grey if you need longer than 100s connections on free/Pro, or upgrade plan.
Step 2: Turn grey while issuing the SSL cert
1. Cloudflare DNS panel
2. Click the orange cloud next to the apex (or www) record
3. It turns grey
4. Wait ~30 seconds for DNS to propagate at Cloudflare edge
5. Re-trigger SSL issuance at your platform
6. Wait for "issued" status
7. Click grey cloud back to orange (if you want Cloudflare in front)
After issuance you can re-enable orange. Your platform’s cert is preserved on the origin; Cloudflare layers its own edge cert on top.
Step 3: Set the right SSL mode for Cloudflare-to-origin
In Cloudflare dashboard → SSL/TLS → Overview:
| Origin state | Required Cloudflare mode |
|---|---|
| Origin has Let’s Encrypt / public CA cert | Full (strict) |
| Origin has self-signed cert only | Full |
| Origin only listens on HTTP :80 | Flexible (avoid in production) |
| Origin has Cloudflare Origin Cert | Full (strict) |
Flexible makes Cloudflare-to-origin plain HTTP and reports HTTPS to user — looks “secure” but is not, and triggers redirect loops if the origin also redirects to HTTPS.
Step 4: For WebSocket needs, choose grey or upgrade plan
If your app needs long-lived sockets:
- Option A: Move WebSocket traffic to a dedicated subdomain (
ws.yourdomain.com), keep that record grey. HTTP traffic at apex stays orange. - Option B: Upgrade to Cloudflare Business or Enterprise, which removes the 100-second cap.
- Option C: Use Cloudflare Spectrum (Enterprise) for full TCP proxying without the WebSocket HTTP envelope.
Step 5: If you need grey cloud for testing, set a calendar reminder
A common pattern: flip grey to debug, forget, weeks pass. Set:
echo "CHECK CLOUDFLARE: did we re-enable orange on apex?" | at now + 2 hours
Or a Slack/Linear reminder. Forgetting orange means losing WAF, DDoS, Workers, cache.
Step 6: Verify origin IP exposure if grey
If you intentionally went grey, audit:
dig yourdomain.com +short
# returns origin IP directly — anyone can find it
Mitigations:
- Configure origin to accept connections only from Cloudflare IP ranges (
https://www.cloudflare.com/ips-v4/) — but only if you plan to flip back to orange. - If permanently grey, treat the origin as exposed: real firewall, fail2ban, normal DDoS prep.
Verify
curl -I https://yourdomain.comreturnscf-ray:header when expecting orange, and lacks it when expecting grey.dig yourdomain.com +shortreturns Cloudflare IP ranges (104.x, 172.67.x) for orange, your origin IP for grey.- SSL cert chain in browser DevTools: orange → cert issued to your domain, issuer “Cloudflare Inc ECC CA-3” or similar; grey → cert issued by Let’s Encrypt or your origin’s CA directly.
- WebSocket connections survive past 100s if you needed grey or upgraded plan.
- Workers / Page Rules / Cache Rules show traffic (non-zero requests) in dashboard for orange records.
Long-term prevention
- Treat the cloud icon as a “production toggle” that requires a teammate review, not a casual flip.
- Document per-record intended state in your DNS-as-code repo (Terraform
cloudflare_recordproxied = true/false) — diff catches accidental flips at PR time. - Use Cloudflare’s audit log to alert on any DNS change; review weekly.
- Pair every grey-cloud event with a follow-up task to flip back, with deadline.
- Standardize SSL mode at Full (strict) and provision Cloudflare Origin Certs for all origins — eliminates the Flexible / Full ambiguity entirely.
Common pitfalls
- Going grey to issue a cert, forgetting to go back orange — losing CDN, WAF, and origin masking silently.
- Setting SSL mode to Flexible because “it just works in browser” — your traffic from CF to origin is plain HTTP and any auth header is exposed.
- Trying to orange-cloud an MX record (Cloudflare blocks this) and being confused by the error.
- Putting apex CNAME on grey and seeing intermittent failures on resolvers that don’t accept apex CNAMEs — flatten requires orange.
- Forgetting that Cloudflare orange terminates client TLS at the edge, so origin cert mismatch is invisible to browser but breaks Full-Strict mode.
FAQ
Q: Why does my Let’s Encrypt cert say “Cloudflare Origin CA” in the browser?
It doesn’t — what the browser sees is Cloudflare’s edge cert, issued by Cloudflare to your domain. Your origin’s Let’s Encrypt cert exists between Cloudflare and origin (or doesn’t, if you’re on Flexible). The browser never sees the origin cert when orange.
Q: Can I have orange on apex but grey on www, or vice versa?
Yes. Each record has its own cloud state. Just be careful that redirects between them (root to www or vice versa) account for which side has Cloudflare in front.
Q: My WebSockets work fine on orange. Did the 100s limit go away?
Either your sockets reconnect transparently (Socket.IO does this), or you’re on a paid plan that extends the limit, or your sockets are short-lived. The limit applies to a single idle TCP connection without data, not to logical sessions.
Q: I see “Error 526” — what is it?
Cloudflare-to-origin SSL handshake failed in Full (strict) mode. Your origin cert is expired, self-signed, or for a different hostname. Either fix the origin cert or switch SSL mode to Full (without strict, which accepts self-signed).
Related reading: SSL cert delay, SSL mixed content warning, HTTPS not forced, and A vs CNAME confusion.