TrafficTriage

Noindex Detected in X-Robots-Tag Header: Find the Source

By Ugur Saritepe · July 24, 2026

Search Console rejected your page with “noindex” detected in “X-Robots-Tag” http header, and you cannot find a noindex anywhere: not in your HTML, not in your code. That is the trap. This noindex is not in your page. It is an HTTP header, attached by whatever serves the response: your host, a plugin, a config file, or a CDN. Here is how to find which layer.

The 60-second self-diagnosis

First, re-read the exact error wording, because Google has two near-identical messages and they point at different places. If it says 'noindex' detected in 'robots' meta tag, the noindex is a line inside your HTML and view-source will show it. If it says 'noindex' detected in 'X-Robots-Tag' http header, view-source is useless: the noindex travels outside the HTML, in the response headers. This guide is for the header case.

Second, reproduce it. Run this against the exact URL Search Console inspected, not just your homepage:

curl -sI https://yourdomain.com/the-exact-page | grep -i x-robots-tag

The five causes, in order of likelihood

1. Google inspected a preview or staging address, not production

Deployment platforms attach X-Robots-Tag: noindex to their non-production URLs on purpose. As of July 2026, Vercel adds it to every preview deployment, documented in Vercel's knowledge base and confirmed on our own previews. Netlify does the same on deploy previews, per its support forum. Managed hosts often do it on staging subdomains like staging.yourdomain.com, and if you verified a Domain property in Search Console, those subdomains are inside it, so Google reports on them too.

30-second check: compare the address in the Search Console report with your production address, character by character. Then curl both. Good: production prints nothing, only the preview or staging host prints noindex; that header is doing its job and needs no fix. Bad: your production URL prints noindex; keep reading.

If the noindex only exists on a preview or staging address, stop here. Do not fight the header. Inspect the production URL instead, and make sure your sitemap and canonical tags only ever mention production so Google stops visiting the wrong host.

2. A header rule in your own repo or server config

The second most common source is a rule you or a teammate added months ago: a “hide staging from Google” header that was supposed to be conditional and leaked into production. One grep finds it:

grep -rni "x-robots-tag" . --exclude-dir=node_modules

Places it hides: the headers() function in next.config.js, a vercel.json or netlify.toml headers block, a _headers file, an .htaccess line like Header set X-Robots-Tag "noindex", or an nginx add_headerdirective on the server itself. The environment-conditional version deserves special suspicion: a check like “add noindex unless this is production” silently fails when the environment variable it reads is missing or renamed.

Good: zero hits outside node_modules and this article. Bad: a hit in any config file; delete the rule or fix its condition, redeploy, and curl again.

3. On WordPress: a plugin or your host, never the checkbox

Here is the detail that ends most WordPress hunts: the famous Settings, Reading, “Discourage search engines” checkbox does not set this header. Since WordPress 5.3 it outputs a robots meta tag, per the WordPress core announcement. So when Search Console names the http header on a WordPress site, the source is a layer that can write headers: a security, maintenance-mode, coming-soon, or SEO plugin; an .htaccess line; or the hosting control panel, which on some servers injects noindex onto dev and staging subdomains.

30-second check:curl the page, deactivate the most likely plugin (anything with “maintenance”, “coming soon”, or “security” in the name), curl again. Repeat down the plugin list. If the header survives with every plugin off and .htaccess clean, it is coming from above WordPress: ask your host what adds X-Robots-Tag on your account.

4. A CDN or proxy in front of your server adds it

Everything between your server and Google can rewrite headers: CDN transform rules, a load balancer, a reverse proxy another team manages. The test is differential: ask your origin server directly, bypassing the CDN, and compare answers. If you know your origin's IP address:

curl -sI --resolve yourdomain.com:443:YOUR_ORIGIN_IP https://yourdomain.com/ | grep -i x-robots-tag

Good: origin and public URL answer identically; the CDN is innocent, look at causes 2 and 3 again. Bad:the origin is clean but the public URL carries noindex; the layer in between added it, so the fix lives in that product's header or transform rules, not in your code. While you are here, also test with a Googlebot user agent: some firewalls answer bots differently than browsers, a separate failure mode we cover in our guide to sites that block their own SEO checks.

5. The header is already gone and Google is behind

Search Console's Pages report can lag the live site by days or weeks. If your curl prints nothing on the exact inspected URL, do not start tearing config apart. Open URL Inspection and click Test live URL: that fetch happens now, against the current site.

Good: the live test says indexing is allowed; the problem is already solved and only the queue remains, so request indexing and move on. Bad: the live test still reports the header even though your curl does not; Google is being served a different response than you, which means a variant URL (www vs non-www, http vs https, trailing slash) or a bot-specific rule; curl each variant until you reproduce it.

What to do next, in order

  1. Re-read the error: robots meta tag means view-source and your HTML; X-Robots-Tag http header means this list.
  2. Curl the exact inspected URL. Header on a preview or staging address only: stop, inspect production instead (cause 1).
  3. Grep your repo and server config for x-robots-tag (cause 2).
  4. On WordPress: plugins, then .htaccess, then ask your host (cause 3).
  5. Differential curl: origin vs public URL, browser agent vs Googlebot agent (cause 4).
  6. Everything clean? Run Test live URL and request indexing (cause 5).

How to confirm the fix worked

Three gates, in order. First, the terminal: curl -sI on the page prints no x-robots-tag line containing noindex. Second, URL Inspection, Test live URL, and the result reports that indexing is allowed. Third, the queue: click Request Indexing on the page, and if the error came from the Pages report, click Validate Fix there. The live test flips immediately; the report itself catches up over days to a few weeks. If the live test still fails, the header is still being served to Google and you stopped one layer too early.

What we see running this check every day

The free triage scan we run on submitted sites fetches the homepage live and reads this exact header on every single run, because one header value outweighs almost anything else on the page: if it contains noindex, the engine flags the site Critical on the spot, no matter how good the content is.

And the layer story is real. This site is one codebase deployed on Vercel, and in July 2026 its addresses answer three different ways: traffictriage.com serves 200 with no X-Robots-Tag at all, traffictriage.vercel.app also serves it clean (with a canonical tag pointing at the real domain), and every preview deployment of the very same code carries X-Robots-Tag: noindex. Same repository, three answers, and only the serving layer decides. That is why hunting by layer finds this in minutes while re-reading your own code finds nothing, and why Google's own documentation treats the header and the meta tag as separate mechanisms.

FAQ

Is X-Robots-Tag the same as the robots meta tag?

They carry the same directives but live in different places. The robots meta tag sits in your HTML head, so you can see it in view-source. X-Robots-Tag is an HTTP response header, sent before any HTML, set by your server, host, plugin, or CDN. Search Console names which one it found, so read the error wording exactly.

Why can't I see the noindex header in my page source?

Because headers are not part of the HTML. View-source will never show it. Check it with curl -sI yoururl in a terminal, or in your browser's developer tools: Network tab, click the first document request, read the Response Headers section.

How long after removing the header until Google indexes the page?

The live test confirms the fix in seconds: URL Inspection, Test live URL, and the result should say indexing is allowed. Actual re-indexing takes days to a few weeks. Use Request Indexing on the important pages and Validate Fix in the Pages report to speed up the queue.

Should I remove the noindex header from preview deployments?

No. Vercel and Netlify add it to previews on purpose, and it protects you: without it, half-finished branch deploys compete with your real site in Google. The fix is never to strip the header from previews. It is to make sure Google is looking at your production URL.

Not sure whether a stray noindex, or something else entirely, is what is holding your site back? Paste your URL into the free Triage Report: it runs 8 checks live against your site, including this exact header on your homepage, scores each one Critical, Monitor, or Healthy, and shows the results on screen in about 30 seconds. No signup, no email. More diagnosis guides live in our symptom guides.

Do this from your editor

Let Claude or Cursor run these checks for you

TrafficTriage has an MCP server. Add one URL to your AI assistant and it can run the 8 checks on any site, read your Search Console data, and pull back your past reports. The verdict lands in a chat that can already see your code, so “why is this happening” and “fix it” are the next two messages. Free account, read-only, nothing to install.

Set up the MCP server