"Excluded by 'noindex' tag" in Search Console
Google found this page, crawled it, and was told not to index it. Here is where that instruction comes from, the four places it hides, and how to confirm it is gone.
This URL is not indexed and it should be. Something is in the way.
Is it still happening?
Paste the URL Search Console flagged. We fetch it, read the HTML and the response headers, and report every robots directive we find and which of them actually blocks indexing.
Whether a noindex directive is on this URL right now, and exactly which source it comes from.
We read the HTML as served, so a noindex injected by client-side JavaScript after the page loads will not appear here. Google renders JavaScript before it decides, so if this check is clean and Search Console still disagrees, use URL Inspection and look at the rendered HTML.
What this error actually means.
Google reached the page without any trouble. Nothing is blocking the crawl, the server returned the page, and the HTML parsed. Then it read an instruction saying "do not put this in the index" and obeyed it.
This is the one indexing error that is never ambiguous. Google is not making a judgement call about quality or duplication. It is following an explicit directive that exists somewhere in your response. Your job is to find where.
It is also the error most likely to be a deployment accident rather than a decision. A noindex that was correct on staging is still correct-looking in production, and nothing about the page renders differently, so it survives review.
5 things that produce this error.
Ordered by how often they turn out to be the cause, not by how obvious they look.
A robots meta tag in the HTML
The obvious one, and the first place to look. It sits in the <head> and is invisible in the rendered page. Note that "none" is shorthand for "noindex, nofollow" and blocks indexing just as completely.
<meta name="robots" content="noindex" />
<meta name="robots" content="none" />
<meta name="googlebot" content="noindex" />An X-Robots-Tag response header
The same directive delivered over HTTP instead of HTML. It never appears in "view source", which is why it survives an entire debugging session. CDNs, reverse proxies, and hosting platforms all add it, and a rule scoped to a staging hostname gets copied to production more often than anyone admits.
HTTP/2 200
content-type: text/html; charset=utf-8
x-robots-tag: noindex, nofollowA framework or CMS setting that writes the tag for you
Next.js metadata with robots.index set to false, the WordPress "Discourage search engines" checkbox under Settings > Reading, a Yoast or Rank Math per-post toggle, Shopify theme conditionals, a Webflow page setting. In every case the tag is generated, so grepping your source for "noindex" finds nothing.
// app/some-page/page.tsx
export const metadata = {
robots: { index: false }, // renders <meta name="robots" content="noindex">
};An environment variable that never got flipped
The pattern that causes the most damage: a conditional that emits noindex unless an environment flag says production. It works perfectly in every environment where the flag is set, and fails silently in the one where a deploy config was copied without it.
const noindex = process.env.VERCEL_ENV !== 'production';
// One missing env var on one deploy and the whole site goes dark.A canonical pointing at a page that is itself noindexed
Less common and harder to spot. If this URL canonicalises to another URL, Google evaluates the target's directives. A clean page canonicalising to a noindexed one inherits the exclusion.
How to clear it.
Find every source before you change anything
There are only four places the directive can come from: the HTML meta tag, the X-Robots-Tag header, the canonical target, and your CMS or framework config. Check all four. Removing one and shipping is how this error comes back a week later, because the second source was doing the work all along.
# Headers, including X-Robots-Tag
curl -sI https://example.com/page | grep -i x-robots-tag
# The meta tag in the raw HTML, before any JS runs
curl -s https://example.com/page | grep -i 'name="robots"'Remove the directive, do not invert it
Delete the tag rather than replacing it with content="index, follow". Indexing is the default, so the positive directive adds nothing, and leaving a robots tag in place keeps the mechanism alive for the next person who edits it by hand.
Make the staging block impossible to leak
If you noindex non-production environments, key the condition on something that cannot silently default to the wrong value. Assert on the hostname you actually serve rather than trusting an env var to be present, and fail loudly when it is missing.
const host = headers().get('host') ?? '';
const isProduction = host === 'example.com';
// Absent config now means indexable, not invisible.Then ask Search Console to look again
Open the Page indexing report, click into the "Excluded by 'noindex' tag" row, and use Validate Fix. Without it you are waiting on the natural recrawl, which for a low-traffic URL can be weeks. URL Inspection > Request Indexing does the same job for a single important page.
Next to check.
LintPage rules covering this: robots-noindex, x-robots-tag, canonical-url
Questions, answered.
How long does it take for a page to be indexed after removing noindex?
Is 'Excluded by noindex tag' always a problem?
Why does the noindex not appear when I view source?
Does robots.txt cause this error?
What is the difference between noindex and nofollow?
Catch this one before Search Console does.
Search Console tells you weeks after the fact. LintPage runs 60 checks against a URL in about 30 seconds. Free, no signup.
run a full scan →