Putting Cloudflare in front of WordPress is one of the cheapest performance and security upgrades you can make to a site. It is also one of the easiest things to misconfigure into a redirect loop, a broken WooCommerce checkout, a wp-admin that nobody can log in to, or a site that quietly serves the wrong cached HTML to half its visitors. The goal of this article is the correct setup, in order, with the conflicts called out where they happen.
How Cloudflare sits between visitors and your WordPress server
When you add a domain to Cloudflare and switch your nameservers, every request to your site stops going to your hosting provider directly. Instead the request hits a Cloudflare data center close to the visitor, and Cloudflare decides what to do with it: serve a cached response from the edge, fetch a fresh copy from your origin, block the request as a threat, or proxy it through to your origin server unchanged. The origin server is your actual WordPress install. Cloudflare is a reverse proxy in front of it.
That single architectural change is the source of every Cloudflare-and-WordPress problem and every Cloudflare-and-WordPress benefit. WordPress no longer sees the visitor's IP address (it sees a Cloudflare IP). HTTPS is now terminated at Cloudflare and the connection between Cloudflare and your origin is a separate one. The cache that determines what visitors see is not your WordPress page cache anymore, it is whatever Cloudflare has stored at the edge. Every misconfiguration in this article is a case of one of those three things being wrong. To understand the layers Cloudflare sits in front of, see how WordPress caching actually works.
Orange cloud (proxy) vs grey cloud (DNS only)
Cloudflare's DNS dashboard shows an orange or grey cloud icon next to every record. The cloud is not decorative. It controls whether traffic for that hostname is proxied through Cloudflare or just resolved by Cloudflare's DNS and then connected to directly.
- Orange cloud (proxied): the visitor connects to Cloudflare. Cloudflare connects to your origin. SSL termination, caching, WAF, DDoS mitigation, and edge logic all apply. This is what you want for
@,www, and any other web hostname. - Grey cloud (DNS only): Cloudflare just answers the DNS query with your real origin IP. The visitor connects to your server directly. None of Cloudflare's protection or caching applies. Use grey cloud for anything that is not HTTP/HTTPS web traffic, and for any hostname Cloudflare cannot proxy.
Two categories of records must always stay grey:
- Mail records.
MXrecords are not proxiable at all (Cloudflare does not show the cloud icon for MX). AnyAorAAAArecord used as a mail server hostname (typicallymail.example.com) must be set to DNS Only. SMTP traffic does not go through Cloudflare's HTTP proxy, so an orange-cloudedmail.record would silently break inbound and outbound email. For more on SMTP and DNS records for WordPress mail, see the official Cloudflare email DNS guide. - FTP, SSH, database, and other non-HTTP services. Cloudflare's standard plans only proxy HTTP and HTTPS on a fixed list of ports. Any hostname you use for SFTP, SSH, MySQL, or another service must be DNS Only or you will not be able to connect.
This is the single most common Cloudflare-onboarding mistake on a WordPress site: someone proxies the mail record along with everything else, email stops working an hour later, and the connection between the two events is not obvious.
SSL/TLS mode: why Full (Strict) is the only safe option
Cloudflare offers five SSL/TLS modes for the connection between Cloudflare and your origin. Only one of them is correct for a WordPress site that has a valid certificate at the origin, and one of the others is the cause of more redirect loops than any other Cloudflare setting.
| Mode | Browser to Cloudflare | Cloudflare to origin | Origin cert validated | Use when |
|---|---|---|---|---|
| Off | HTTP | HTTP | No | Never (no encryption anywhere) |
| Flexible | HTTPS | HTTP | No | Never on a real WordPress site |
| Full | HTTPS | HTTPS | No | Origin has self-signed cert only |
| Full (Strict) | HTTPS | HTTPS | Yes | Default. Origin has Let's Encrypt or Cloudflare Origin CA |
| Strict (SSL-Only Origin Pull) | HTTPS or HTTP | HTTPS always | Yes | Enterprise; never downgrade |
Cloudflare's own documentation explicitly recommends Full or Full (Strict) "whenever feasible" and warns that Flexible should not be used with sites that handle sensitive data, which includes anything with a login. WordPress has a login. Use Full (Strict).
Why Flexible mode causes redirect loops
Flexible mode looks attractive because the origin does not need a certificate, so you can skip the Let's Encrypt step. Every WordPress site I have seen that picked Flexible "to keep things simple" eventually ran into the same loop:
- A visitor requests
https://yoursite.nl. - Cloudflare Flexible mode sends an HTTP request to your origin (port 80, no encryption).
- Your nginx or Apache config has a
return 301 https://...rule, or WordPress hasFORCE_SSL_ADMINset, or a security plugin enforces HTTPS. The origin sends back a 301 redirect tohttps://yoursite.nl/whatever. - Cloudflare receives the HTTPS redirect, sends another HTTP request to the origin.
- Step 3 repeats. The browser surfaces
ERR_TOO_MANY_REDIRECTS.
This is the most common single cause of the Too Many Redirects error in WordPress. Cloudflare's own troubleshooting page says the fix is to switch to Full (Strict) and install a valid origin certificate. Do that.
If you cannot install a certificate at the origin yet, Cloudflare's free Origin CA certificate is signed by Cloudflare and trusted automatically when traffic flows through Cloudflare's proxy. You generate it from the SSL/TLS dashboard, install it on your origin, and from that point on the connection between Cloudflare and your origin is encrypted and validated. Important caveat: an Origin CA certificate is not trusted by browsers directly, so if you ever turn off the orange cloud and visitors hit your origin without Cloudflare in front, they will see SSL errors. That is the trade-off and it is rarely a problem in practice as long as you remember it.
Setting up Cloudflare for WordPress: the correct sequence
The order matters. If you change DNS first and SSL second, your site is broken between those two steps. If you turn on Always Use HTTPS before Cloudflare's certificate is provisioned, the same thing happens. This is the sequence I use:
- Make sure your origin has a valid HTTPS certificate. Let's Encrypt via your hosting panel is the easiest path. If your host does not offer one, generate a Cloudflare Origin CA certificate from the Cloudflare dashboard later in step 7 and install it then.
- Add the domain to Cloudflare through the dashboard. Cloudflare will scan your existing DNS records and import them. Verify that all records were imported correctly. Pay particular attention to
MX,mail.,webmail.,imap.,smtp.,cpanel., and any subdomains for non-web services. - Set the cloud icon correctly on every record. Web hostnames (
@,www) get orange clouds. Everything mail-related gets grey clouds. Everything non-HTTP gets grey clouds. Double-check this before changing nameservers. - Switch your nameservers at your domain registrar to the two Cloudflare nameservers Cloudflare assigns to your zone. Wait until Cloudflare's status page for the zone shows "Active" before continuing. This usually takes minutes, occasionally hours.
- Set SSL/TLS mode to Full (Strict). Dashboard: SSL/TLS, Overview, set encryption mode to Full (strict). Verify the site loads on HTTPS in a private browser window. If you see
ERR_TOO_MANY_REDIRECTShere, jump to the redirect-loop section above. - Enable Always Use HTTPS. Dashboard: SSL/TLS, Edge Certificates, Always Use HTTPS. This makes Cloudflare 301-redirect any plain HTTP request to HTTPS at the edge, before the request even reaches your origin. With Full (Strict) plus Always Use HTTPS enabled, you can safely remove the HTTP-to-HTTPS redirect from your origin's nginx or Apache config (if you have one). One redirect is enough.
- Install the Cloudflare WordPress plugin. Search the plugin directory for "Cloudflare", install version 4.14.2 or later (released December 2025), and connect it to your Cloudflare account using a scoped API token. The plugin enables APO if you choose to turn it on, automatically purges the Cloudflare cache when you publish or update content, and exposes a few Cloudflare settings inside wp-admin.
- Configure cache rules as described in the cache rules section below. Without explicit cache rules, Cloudflare caches your static assets but not your HTML. Most of the speed gain from Cloudflare on a WordPress site comes from caching HTML at the edge.
- Verify the proxy header trick in
wp-config.phpif WordPress still thinks the connection is HTTP. See the "X-Forwarded-Proto and reverse proxy detection" section.
After step 6, the site should be working: HTTPS at the front, valid certificate, no redirect loops, mail still flowing. Steps 7 to 9 are about turning Cloudflare from a security and basic CDN layer into a full edge cache for WordPress.
Page Rules are deprecated: use the new Rules system
If you read older Cloudflare-and-WordPress articles, almost every cache or redirect recipe in them is written as a Page Rule. Page Rules are no longer the way to configure Cloudflare. According to Cloudflare's Page Rules migration guide, since January 6, 2025 no Cloudflare account on any plan can create new Page Rules. Existing Page Rules continue to function and Cloudflare is migrating them automatically to the new system, but for any new configuration you need to use the replacement products.
| Old Page Rules setting | New product | Where in the dashboard |
|---|---|---|
| Cache Level / Cache Everything | Cache Rules | Caching, Cache Rules |
| Browser Cache TTL, Edge Cache TTL | Cache Rules | Caching, Cache Rules |
| Always Use HTTPS for a path | Single Redirects (Redirect Rules) | Rules, Redirect Rules |
| Forwarding URL (301/302) | Single Redirects | Rules, Redirect Rules |
| SSL mode per URL | Configuration Rules | Rules, Configuration Rules |
| Security Level per path | Configuration Rules | Rules, Configuration Rules |
| Host Header Override | Origin Rules | Rules, Origin Rules |
The behavioral difference that bites people: the new Rules are stackable. Multiple rules can match a single request and all of them apply. Page Rules used first-match-wins, where only one rule was applied per request. If you are migrating old configurations by hand, do not assume that copying a Page Rule into a Cache Rule produces the same effect, especially when more than one rule could match the same URL.
The free plan allows ten Cache Rules and ten Redirect Rules, which is enough for a normal WordPress site. The four cache rules below leave six free for anything else.
Cache rules: what to cache, what to bypass
Cloudflare does not cache HTML by default. Out of the box, the orange cloud caches your static assets (CSS, JS, images) and protects you, but every page request still hits your origin and runs PHP and queries the database. To get the actual edge-cache speedup on WordPress, you need to tell Cloudflare to cache HTML and to bypass the cache for the requests that must not be cached. The wrong bypass list is how you serve a logged-in admin's wp-admin page to a random anonymous visitor.
The minimum safe ruleset for WordPress, in order:
Rule 1: bypass cache for logged-in users and admin paths.
- When incoming requests match: Cookie name contains
wordpress_logged_in_OR URI Path starts with/wp-admin/OR URI Path equals/wp-login.phpOR URI Path starts with/wp-json/ - Then: Bypass cache
This protects the entire admin experience and the REST API from being cached. The wordpress_logged_in_ cookie is set whenever someone is logged in, regardless of role. The /wp-json/ bypass keeps Gutenberg and the block editor from being served stale data.
Rule 2: bypass cache for WooCommerce sessions and cart cookies.
- When incoming requests match: Cookie name contains
woocommerce_items_in_cartORwoocommerce_cart_hashORwp_woocommerce_session_ - Then: Bypass cache
The wp_woocommerce_session_ cookie prefix carries the visitor's session ID for the cart. If you cache pages that include any of these cookies, two visitors can end up sharing each other's cart contents. This rule prevents that.
Rule 3: bypass cache for WooCommerce path prefixes.
- When incoming requests match: URI Path starts with
/cart/OR/checkout/OR/my-account/ - Then: Bypass cache
This is a defense in depth for WooCommerce: the cookie rule above is the primary protection, but if cookies somehow miss the page, the path rule still keeps cart, checkout, and account pages out of the cache. Cloudflare's WooCommerce caching guide covers the same exclusions.
Rule 4: cache HTML for everything else.
- When incoming requests match: All incoming requests (or, more conservatively, URI Path does not start with
/wp-admin/and Hostname equals your domain) - Then: Eligible for cache; Edge TTL: respect existing headers (recommended) or 4 hours; Browser TTL: respect existing headers
This is the one that actually makes Cloudflare cache HTML at the edge. Without it, Cloudflare follows its default behavior, which is to cache only the static asset extensions it knows about. The "respect existing headers" option lets WordPress and your caching plugin control TTL via Cache-Control headers, which is the safest default if you have a WordPress page cache plugin already.
A note on the free plan: Cloudflare's edge cache TTL plan limits set the minimum edge TTL on the free plan at two hours. That means even if WordPress sends Cache-Control: max-age=300, Cloudflare on the free plan will hold the page at the edge for at least two hours. If you publish or update a post, you need the Cloudflare WordPress plugin to issue an automatic cache purge, otherwise visitors can see a stale page for up to two hours.
APO: what it does and when it helps
Automatic Platform Optimization is Cloudflare's name for caching full HTML pages at the edge using Cloudflare Workers, with WordPress-aware logic that automatically bypasses cache for logged-in users and WooCommerce sessions. APO launched on October 2, 2020 during Cloudflare's Birthday Week. Cloudflare's launch post reported a 72% reduction in TTFB at the 90th percentile on test sites.
APO is a $5 per month add-on on the free plan and included free on Pro, Business, and Enterprise plans. To use it you also need the Cloudflare WordPress plugin installed, because the plugin handles the cache-purge-on-publish logic. Without the plugin APO still caches HTML, but with a fixed 30 minute TTL and no intelligent purging, which is rarely what you want.
The honest comparison between APO and manual Cache Rules:
| APO | Manual Cache Rules | |
|---|---|---|
| Caches HTML at the edge | Yes (via Workers) | Yes (if rule 4 is configured) |
| Auto-bypass for logged-in users | Yes | Manual rule required |
| Auto-bypass for WooCommerce sessions | Yes | Manual rule required |
| Cache purge on post publish/update | Yes (via plugin) | Plugin or manual |
| Plan requirement | Any (with $5 add-on on Free) | Any |
| Setup complexity | Low | Medium |
| Cost on Free plan | $5/month | Free |
| Cost on Pro+ | Free | Free |
Pick APO if you want the lowest-friction option and you are on a Pro plan (where it is free) or the $5 is fine. Pick manual Cache Rules if you are on the free plan and want zero monthly cost, and you are comfortable maintaining the bypass list yourself. Either approach gives you HTML caching at the edge. There is no third option that is materially better.
There has been some confusion in 2024 and 2025 about whether APO was being deprecated. It was not. Cloudflare did not update the Cloudflare WordPress plugin between August 2024 and October 2025, which led to community speculation, but plugin development resumed in late 2025 and the current version (4.14.2 as of December 22, 2025) is actively maintained and tested up to WordPress 6.9. APO itself remained an active product throughout.
The Cloudflare WordPress plugin
The official Cloudflare plugin on wordpress.org is at version 4.14.2 as of December 22, 2025, has more than 200,000 active installs, and is tested up to WordPress 6.9. It requires PHP 7.4 or newer and WordPress 5.0 or newer.
What the plugin actually does:
- Cache purge on content updates. When you publish, update, or delete a post or page, the plugin issues a Cloudflare API call to purge the edge cache for the URLs that changed. This is the single feature that makes APO usable, and it is also useful with manual Cache Rules.
- Manual cache purge from wp-admin. A button to purge the entire Cloudflare cache for the zone, without leaving WordPress. Useful when you have just made a site-wide change (theme update, CSS change) and you do not want to wait for individual URLs to expire.
- Toggle Cloudflare settings inside wp-admin. Security level, Always Online, Image Optimization. None of this is functionality you cannot reach in the Cloudflare dashboard, but it is convenient if you do not want to context-switch.
- APO control. Enable, disable, and configure APO from inside wp-admin if you have an APO subscription on the zone.
You connect the plugin to Cloudflare with a scoped API token, not the legacy global API key. Generate the token from your Cloudflare account: My Profile, API Tokens, Create Token, use the "WordPress" template. The token only has the permissions the plugin needs, which limits the blast radius if it ever leaks.
X-Forwarded-Proto and reverse proxy detection
When Cloudflare proxies a request to your origin, the visitor's connection to Cloudflare is HTTPS but the connection between Cloudflare and the origin can be HTTP or HTTPS depending on your SSL mode. If your origin sees an HTTP request, PHP's $_SERVER['HTTPS'] is empty and WordPress thinks the visitor is on plain HTTP. That breaks is_ssl(), breaks any HTTPS-aware redirect logic, and contributes to mixed content warnings on the front end. To untangle the front end side, see mixed content warnings in WordPress.
The fix is to read the X-Forwarded-Proto header that Cloudflare always sets and tell WordPress that the connection is secure when the header says https. Add this to wp-config.php before the require_once ABSPATH . 'wp-settings.php' line:
// Trust Cloudflare's X-Forwarded-Proto header.
// Only safe when the origin is not directly reachable without Cloudflare,
// i.e. when the origin IP is firewalled to Cloudflare's IP ranges.
if (
isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] )
&& 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO']
) {
$_SERVER['HTTPS'] = 'on';
}
The security caveat is non-negotiable. If your origin is reachable on a public IP without going through Cloudflare, an attacker can connect directly and send a fake X-Forwarded-Proto: https header, and WordPress will believe them. The X-Forwarded-Proto header in the snippet above is only trustworthy when nothing else can write it, and that means firewalling your origin so only Cloudflare's IP ranges can reach ports 80 and 443. Cloudflare publishes the list of its IPv4 and IPv6 ranges. Your hosting provider should have a guide for restricting your server's firewall to that list.
The same principle applies to recovering visitor IPs in WordPress logs, comment spam heuristics, and rate-limiting plugins. Cloudflare puts the visitor's real IP in the CF-Connecting-IP header. Plugins like Wordfence have built-in modes for reading it. Web servers can be configured to do the same: nginx with ngx_http_realip_module, Apache with mod_remoteip. Without that step, every IP in your WordPress access logs is a Cloudflare IP, which makes country-based blocking and abuse forensics useless.
For more on getting WordPress to handle HTTPS correctly behind a proxy, see how to force WordPress to HTTPS without the redirect loop.
Purging Cloudflare cache after content updates
With Cache Rules or APO caching HTML at the edge, every published post is two caches at once: the WordPress page cache (or APO's edge cache) at one layer, and Cloudflare's edge nodes at another. Updating a post in wp-admin clears the WordPress side but does nothing to the Cloudflare side unless something explicitly tells Cloudflare to purge.
The Cloudflare WordPress plugin handles this automatically for posts and pages: when you save a published post, it issues a POST /zones/{zone_id}/purge_cache call to the Cloudflare API for the affected URLs. APO subscribers get the same behavior with extra logic that knows about archive pages, category pages, and the home page. Without the plugin, you have to purge manually from the Cloudflare dashboard, or write your own purge logic with the API.
The WordPress page cache plugin you already have (LiteSpeed Cache, WP Rocket, W3 Total Cache, FlyingPress) often has its own Cloudflare integration that does the same job. Pick one. Running two plugins that both try to manage the Cloudflare cache produces unpredictable purge timing and occasional missed invalidations. If you go with the official Cloudflare plugin, disable the Cloudflare integration in your page cache plugin. If you go with your page cache plugin's integration, you do not need the Cloudflare plugin for purges, but you might still want it for APO.
Common conflicts and how to recognize them
Conflict 1: redirect loop after enabling Cloudflare
Symptom: the site that worked fine yesterday now shows ERR_TOO_MANY_REDIRECTS in every browser, immediately, before any page content loads.
Cause: SSL/TLS mode is set to Flexible (or Off) and the origin has its own HTTP-to-HTTPS redirect.
Fix: switch SSL/TLS mode to Full (Strict) and install a valid origin certificate (Let's Encrypt or Cloudflare Origin CA). If you cannot do that immediately, remove the origin's HTTP-to-HTTPS redirect and rely on Cloudflare's "Always Use HTTPS" instead. Both fixes break the loop.
Verify: open the site in a private window. The page should load on https:// without errors. Run curl -I https://yoursite.nl from a terminal and confirm the response is HTTP/2 200, not a chain of 301s.
Conflict 2: WooCommerce checkout shows another visitor's cart
Symptom: customers report seeing items in their cart that they did not add, or the wrong total at checkout, or a logged-in account header for a user who is not them.
Cause: Cloudflare is caching pages that include WooCommerce session cookies, and serving the same cached page to multiple visitors. Either the bypass rules for woocommerce_* cookies are missing, or the path bypass for /cart/, /checkout/, and /my-account/ is missing, or both.
Fix: add the cookie bypass rule and the path bypass rule from the cache rules section above. After adding them, purge the entire Cloudflare cache (Caching, Configuration, Purge Everything) so the polluted entries are evicted.
Verify: add a product to your cart, log out, open a private window, and visit the same URL. The private window should show an empty cart, not yours.
Conflict 3: wp-admin loads stale pages or login fails
Symptom: changes you make in wp-admin do not appear when you reload, or you get logged out unexpectedly, or the Customizer shows the wrong content.
Cause: Cloudflare is caching wp-admin pages, the REST API, or the wordpress_logged_in_ cookies are not in the bypass list. Cloudflare Rocket Loader (a JavaScript optimization) can also break wp-admin scripts.
Fix: confirm that Cache Rule 1 includes wordpress_logged_in_ and /wp-admin/ and /wp-json/. In Cloudflare, go to Speed, Optimization, and disable Rocket Loader globally, or disable it for /wp-admin/* with a Configuration Rule. After changing rules, purge everything.
Verify: log in to wp-admin in a private window. Make a content change. Reload the public site immediately. The change should be visible.
Conflict 4: email stops working after onboarding
Symptom: outbound email from contact forms stops being delivered, or inbound mail to your domain bounces, an hour or two after switching nameservers to Cloudflare.
Cause: the MX record points at a hostname like mail.yoursite.nl and that hostname's A record was orange-clouded during onboarding. Cloudflare does not proxy SMTP, so mail traffic cannot reach your real mail server.
Fix: in Cloudflare DNS, find every A and AAAA record for mail, smtp, imap, pop, webmail, or any other mail-related hostname, and click the orange cloud to turn it grey. MX records are non-proxiable by default and do not need to be touched.
Verify: send a test email from a contact form on the site, and send an email from an external account to your domain. Both should arrive within a minute. Check your DNS records with dig mail.yoursite.nl A +short and confirm the answer is your real mail server IP, not a Cloudflare IP (Cloudflare IPs typically start 104.16., 104.17., 172.64., or similar).
Conflict 5: visitor IPs in WordPress logs are all Cloudflare
Symptom: Wordfence, Limit Login Attempts, or any analytics plugin shows every visitor coming from a Cloudflare IP, country-blocking does not work, comment spam heuristics misfire.
Cause: WordPress and the web server are reading the immediate connection IP, which is Cloudflare. The visitor's real IP is in the CF-Connecting-IP header.
Fix: configure your web server to restore the real client IP from CF-Connecting-IP. On nginx, use ngx_http_realip_module with set_real_ip_from rules for Cloudflare's IP ranges. On Apache, use mod_remoteip. Plugins like Wordfence have a built-in setting under Tools, Diagnostics, Other Tests for the IP source. Pick the option that uses CF-Connecting-IP.
Verify: load your site, then check the access log on the origin or check Wordfence's recent visitor list. The IPs should now match your real public IP, not Cloudflare's.
When to escalate
If you have followed the steps above and the site is still broken, the loop still occurs, or the cache is still serving the wrong content to the wrong people, collect the following before asking for help:
- Cloudflare zone name and the plan you are on (Free, Pro, Business, Enterprise)
- SSL/TLS mode currently set (screenshot of the SSL/TLS Overview page)
- Cache Rules and Configuration Rules in place (screenshots, in order)
- Output of
curl -I https://yoursite.nlfrom outside Cloudflare - Output of
curl -I -H "Host: yoursite.nl" https://your-origin-ip/if you can reach the origin directly (only relevant if you have not firewalled the origin to Cloudflare yet) - WordPress version, PHP version, page-cache plugin name and version, Cloudflare WordPress plugin version
- Browser console errors and the network tab waterfall for the failing page
- A clear description of what you have already tried, including any cache purges
That set of information is enough for any Cloudflare-aware support engineer or hosting provider to reproduce the problem on the first try. Without it, you will spend a few hours on back-and-forth messages before anyone can tell you anything useful.
How to prevent recurrence
A small amount of discipline keeps Cloudflare from breaking things twice:
- Document the SSL mode, cache rules, and bypass rules in a place that survives staff turnover. Cloudflare configuration is invisible to the WordPress dashboard, so a future maintainer who only looks at WordPress will not understand why the cache behaves the way it does.
- Audit DNS records after every onboarding. Check that every mail-related record is grey, every web record is orange, and that nothing was missed in the import.
- Keep one cache invalidation source. Either the official Cloudflare plugin handles purges, or your page cache plugin's Cloudflare integration does, never both at the same time.
- Firewall the origin to Cloudflare's IP ranges if you trust
X-Forwarded-Proto. Without that firewall, the proxy header trick is a security hole. - Test in a private browser window after every change. The cache that bites you is almost always the one your logged-in browser is hiding from you.