About This HTML Issue
The HTML specification restricts where <link> elements can appear based on their purpose. Links that load resources needed for rendering (like stylesheets and preloaded assets) or carry microdata (itemprop) are allowed in <body> because they have a direct relationship to the content around them. Other types of <link> elements—canonical URLs, icons, alternate versions—are document-level metadata and belong exclusively in <head>.
This matters for several reasons. Browsers may ignore or inconsistently handle <link> elements placed in unexpected locations, leading to issues like missing canonical signals for search engines or broken favicon references. Standards compliance also ensures your HTML is forward-compatible and behaves predictably across all browsers.
Common causes
Direct placement in <body>
The most straightforward cause is placing a metadata <link> directly inside <body>, often due to a CMS, template system, or plugin injecting it in the wrong location.
Implicit <body> creation by the parser
A subtler cause occurs when an element that’s only valid in <body> appears inside <head>. When the HTML parser encounters such an element (like <img>, <div>, or <p>), it implicitly closes the <head> and opens the <body>. Any <link> elements that follow are then treated as descendants of <body>, even though they appear to be inside <head> in your source code.
For example, an <img> tag in the <head> causes the parser to switch to body context, so the subsequent <link rel="canonical"> is interpreted as being inside <body> and triggers this error.
How to fix it
-
Move disallowed
<link>elements to<head>: If a<link>withrel="canonical",rel="icon",rel="alternate", or similar values is in<body>, move it into<head>. -
Check for body-only elements in
<head>: Look for elements like<img>,<div>,<p>,<script>(withoutsrc), or text content that may have been accidentally placed in<head>. These cause the parser to implicitly close<head>, making everything after them part of<body>. -
Use allowed
relvalues if a body placement is intentional: If you genuinely need a<link>in<body>, ensure it uses one of the permittedrelvalues (stylesheet,preload,prefetch,preconnect,dns-prefetch,modulepreload,pingback,prerender) or has anitempropattribute.
Examples
❌ <link rel="canonical"> placed in <body>
<body>
<link rel="canonical" href="https://example.com/page">
<h1>Welcome</h1>
</body>
✅ Move it to <head>
<head>
<title>My Page</title>
<link rel="canonical" href="https://example.com/page">
</head>
<body>
<h1>Welcome</h1>
</body>
❌ An <img> in <head> forces implicit body context
Even though the <link> appears to be in <head>, the <img> causes the parser to switch to body context:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
<img src="photo.jpg" alt="A smiling cat">
<link rel="canonical" href="https://example.com/">
</head>
<body>
<p>Some content</p>
</body>
</html>
✅ Move the <img> to <body> where it belongs
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
<link rel="canonical" href="https://example.com/">
</head>
<body>
<img src="photo.jpg" alt="A smiling cat">
<p>Some content</p>
</body>
</html>
✅ Allowed <link> elements inside <body>
These are valid because they use permitted rel values:
<body>
<article>
<link rel="stylesheet" href="article-theme.css">
<h2>Article Title</h2>
<p>Content here.</p>
</article>
<link rel="prefetch" href="/next-page.html">
<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin>
</body>
✅ Using itemprop for microdata
A <link> with an itemprop attribute is also valid inside <body>:
<body>
<div itemscope itemtype="https://schema.org/Product">
<span itemprop="name">Widget</span>
<link itemprop="availability" href="https://schema.org/InStock">
</div>
</body>
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.
Learn more: