Your CDN’s Edge Caching Is Breaking Hreflang for International Visitors

On this page

When geo-IP detection or geo-redirects run at your origin behind a location-blind CDN, two failures can stack. The edge caches one country’s response, or one redirect outcome, under the URL alone and serves it to everyone who reaches that node. And if a URL named in your hreflang annotations redirects by location, a crawler arriving from another country is sent away from the localized content the annotation points to. The fix has two parts: add the country to the cache key, and make every hreflang-declared URL serve its declared content to every requester, crawlers included.

The mechanism: a location-blind cache key

A CDN edge decides what to serve by computing a cache key, and by default that key is essentially the URL. If your origin inspects the visitor’s IP and returns a country-specific body or a geo-redirect, but the CDN keys only on the URL, the first request to reach an edge node fills the cache, and later requests for that URL at that node get the same stored response wherever they come from. A visitor in Paris can be served the version a visitor in Chicago triggered moments earlier. The variation you intended collapses into whichever locale filled the cache first.

Why this breaks hreflang

Hreflang annotations are mutual: each localized URL lists itself and its alternates. Google’s guide to localized versions says that if two pages don’t both point to each other, the tags will be ignored, while Google still processes the pairs that do.

Now add the crawler’s location. Google’s locale-adaptive pages documentation says the default IP addresses of Googlebot appear to be based in the USA, and that the crawler sends requests without an Accept-Language header. It also crawls from IP addresses outside the USA. So if your /fr-fr/ URL redirects US-based requests to /en-us/, a crawl from a US address that follows the French alternate never reaches French content. The French page can’t confirm its side of the pairing, and the pairs involving it can be ignored. The pages may each still be indexed, but the pairing that puts the right version in front of the right market is then at risk.

A clean-looking setup can hide this. Search Console’s International Targeting report has been deprecated; Google says it continues to support and use hreflang tags, so don’t count on Search Console to flag hreflang problems for you. The redirect fires at crawl time, and a way to catch it is to check what the crawler receives.

Google’s position on IP-based adaptation

Google is explicit on this point. Its guide to managing multi-regional and multilingual sites says not to use IP analysis to adapt your content, because IP location analysis is difficult and generally not reliable. It also advises against automatically redirecting users from one language version to another, since those redirections could prevent users, and search engines, from viewing all the versions of your site. The locale-adaptive documentation recommends separate locale URLs annotated with hreflang.

That is the design to aim for: stable URLs per locale, each returning its own content, with a language switcher or a non-forcing suggestion for users.

Fix the redirects: hreflang URLs must not geo-redirect

Every URL that appears in an hreflang annotation should serve its declared language and country content to any requester, wherever the request comes from. Remove geo-redirects from those URLs. If you want to help visitors find their version, suggest a locale with a banner or a selector rather than forcing a redirect.

Fix the cache key: add the country

If any response still varies by location, the cache has to stop collapsing those variants into one entry. On Cloudflare, Cache Rules let you build a custom cache key, and Cloudflare’s cache rules settings list Country, alongside device type and language, among the user attributes Enterprise customers can add to it; check what your plan allows. Other stacks do the same with edge logic keyed on country, or with a Vary response the cache honors. Accept the trade: splitting the cache by country lowers the hit ratio per segment because you store more variants. That is the cost of serving the correct locale.

Once the hreflang URLs stop varying by location, the cache key matters less for those URLs, because every requester gets the same body. Keep the country dimension for any page that still adapts by location, such as a homepage that shows a locale suggestion.

Verify what the crawler receives

Don’t read a quiet Search Console as a pass; check the fetch.

  • URL Inspection. Inspect each localized URL in Search Console and confirm the fetched content is the declared language, not a redirect target.
  • Requests from several regions. Request the hreflang URLs directly from different countries, through a VPN or a testing service, and confirm each returns its own content with no 3xx to your default locale.
  • A crawl of the localized set. Use a site crawler to confirm that reciprocal annotations resolve to live, non-redirecting URLs rather than relying on Search Console to surface hreflang problems.
  • Where the geo-logic runs. If it runs at the origin behind a URL-only cache key, you have both failures at once and need to fix them together.

Declaration versus delivery

When an hreflang set breaks, the first stop is the HTML: does every alternate name every other, are the return tags reciprocal? That check is necessary, but it can’t catch this failure, because the markup is static and the failure happens at request time, at the edge, for a particular class of requester. The annotations can be flawless in your editor and in the page you load from your office, and still resolve to the wrong body for a crawler on a US address hitting a cold edge node. The symptom can be intermittent by geography and cache state, may not reproduce when you test from the target country, and leaves nothing static to search for.

A model that helps: stop thinking of an hreflang URL as “a page” and think of it as a contract to return specific content to anyone who asks. A geo-redirect on that URL breaks the contract for out-of-region requesters. A country-blind cache key breaks it for whoever didn’t happen to fill the cache. Both are delivery decisions made below the markup, which is why tidying the annotations doesn’t repair them.

Order of operations

  1. Confirm the symptom. Run URL Inspection on two or three localized URLs and note whether the fetched content matches the declaration or shows a redirect.
  2. Trace the geo-logic. Request a localized URL from outside its region and watch for a 3xx status or a swapped body.
  3. Remove geo-redirects from the hreflang-declared URLs, leaving any non-forcing locale suggestion in place.
  4. Add the country to the cache key for any page that still varies by location.
  5. Re-inspect and re-crawl to confirm each declared URL returns its declared content.

Ship steps 3 and 4 together. Fixing the redirect without the cache key, or the reverse, can leave the symptom half-fixed and harder to read.

Leave a comment

Your email address will not be published. Required fields are marked *