Head Contains Invalid Elements: Why It Drops Your Meta Tags
- December 14, 2020
- Indexation, HTML Head

This check fires when your <head> contains an element that doesn't belong there — a stray <div>, a <p>, an <img>, or even loose text. The stakes are blunt: browsers and Google auto-close the head the instant they hit an invalid element, so anything after that point — your canonical, your meta robots, your hreflang, your Open Graph tags — gets shoved into the body and silently ignored.
Why a single stray tag wipes out your meta tags
The HTML spec allows only a specific, short list of elements inside <head>. When a parser encounters anything else, it doesn't error out — it assumes you forgot to write </head><body> and closes the head for you, right there. Every valid <meta>, <link>, or <script> that came after the offending element is now parsed as body content. A <link rel="canonical"> in the body is not a canonical — it's decoration Google throws away. Same for meta robots, same for hreflang. You didn't lose the tag; you lost its meaning.
Here is a real one — a tracking snippet dumped a <div> into the head, and the canonical below it died:
<head>
<meta charset="utf-8">
<title>Running Shoes</title>
<div id="gtm-noscript"></div> <!-- invalid: head closes HERE -->
<link rel="canonical" href="https://example.com/shoes/running/">
<meta name="robots" content="index, follow">
</head>The browser rewrites that as if </head><body> sat right before the <div>. The canonical and robots tag are in the body now. To Google, this page has no declared canonical and no robots directive — it falls back to defaults and guesses.
The only elements allowed in the head
Allowed in <head> | What it's for | Common invalid intruders |
|---|---|---|
<title> | Page title (exactly one) | <div>, <section> |
<meta> | Charset, robots, viewport, OG/Twitter | <p>, loose text |
<link> | Canonical, stylesheets, hreflang, icons | <img>, <a> |
<style> | Inline CSS | <h1>–<h6> |
<script> / <noscript> | JS and no-JS fallbacks | <iframe>, <table> |
<base> | Base URL for relative links (at most one) | <button>, <form> |
<template> | Inert markup fragment | unencoded &, <, or > as text |
If it isn't in the left column, it terminates the head early. A frequent surprise: raw text — even a stray comment fragment or an ampersand outside a tag — counts as an intruder, because text nodes aren't allowed as direct children of <head> either.
How to detect it
- View Source vs. rendered DOM: open raw source (Ctrl+U) and read the head top to bottom looking for anything that isn't title/meta/link/style/script/base. Then open DevTools Elements and check where
</head>actually sits in the parsed DOM — if it closed earlier than your source shows, the browser found an intruder. The gap between the two views is the tell. - GSC URL Inspection (rendered HTML): inspect the URL, open "View crawled page," and check whether Google's rendered head still contains your canonical and robots tags. If they've fallen into the body, Google is confirming the early-close for you.
- Screaming Frog: crawl, then check whether canonicals and meta robots that should exist show as empty or "Missing." A template that clearly outputs a canonical but reports none across a URL group is a strong signal the head is closing early.
- W3C validator or a linter: run the URL through an HTML validator; "Element X not allowed as child of element head" pins the exact intruder and line number faster than eyeballing.
How to fix it
Find the first invalid element in the head and either move it into the body or delete it. Injected analytics and consent snippets are the usual culprits — a GTM container's <noscript><iframe> block belongs immediately after the opening <body>, not in the head. Corrected:
<head>
<meta charset="utf-8">
<title>Running Shoes</title>
<link rel="canonical" href="https://example.com/shoes/running/">
<meta name="robots" content="index, follow">
</head>
<body>
<div id="gtm-noscript"></div> <!-- moved into body -->Then confirm the fix in the rendered DOM: reload, open DevTools, and verify </head> now closes after your last meta tag. Re-inspect in Search Console so Google re-renders and picks the canonical and robots directive back up. If a plugin or tag manager is injecting the intruder, fix it at the source — patching the output once won't survive the next template render.
False positives and edge cases
Some checkers flag <noscript> or a <script> that itself contains markup-looking strings. Those are valid in the head — a <noscript> holding a <link> or <style> is legal, and a script's inner text isn't parsed as head children. If the tool flags one of these but your canonical and robots tags still resolve correctly in the rendered DOM, it's a false positive; verify with the DOM before you go rearranging templates. The real test is always: does </head> close where you expect in the parsed page?
FAQ
Why does one bad tag kill everything after it and not just itself?
Because the parser reacts to an invalid head child by inserting an implicit </head><body> at that spot. It's not skipping the one tag — it's declaring the head over. Everything downstream inherits body context, so all your remaining meta/link tags become inert.
Will invalid comments break the head?
Well-formed comments (<!-- ... -->) are fine in the head. A malformed comment or raw text that looks like a comment but isn't closed properly can spill into a text node and trip the early-close. When in doubt, validate.
My canonical is in the source — why does Google say it's missing?
Because "in the source" and "in the head" aren't the same thing once an intruder closes the head early. Check the rendered DOM: if the canonical sits below the implicit </head>, Google reads it as body content and ignores it. This is one of the sneakier causes behind a missing canonical tag.
Does this affect meta robots too, or only canonicals?
Everything below the intruder is affected — canonical, meta robots, hreflang, viewport, Open Graph, the lot. If your robots directive fell into the body, Google reverts to indexing defaults. See the meta robots outside head check for the robots-specific symptom of the same root cause.
Where should injected third-party markup go instead?
Non-head elements (iframes, noscript image beacons, divs) belong in the body — typically right after <body>. Only title, meta, link, style, script, base, and template are legal head children. For the full picture of how a broken head cascades into indexing problems, the canonical tags reference walks through discovery and consolidation once your tags actually parse.
Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.
About SEO ProCheck
Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.
Work With Me
Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.







