Skip to main content
HTML Validation

A “link” element must not appear as a descendant of a “body” element unless the “link” element has an “itemprop” attribute or has a “rel” attribute whose value contains “dns-prefetch”, “modulepreload”, “pingback”, “preconnect”, “prefetch”, “preload”, “prerender”, or “stylesheet”.

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

  1. Move disallowed <link> elements to <head>: If a <link> with rel="canonical", rel="icon", rel="alternate", or similar values is in <body>, move it into <head>.

  2. Check for body-only elements in <head>: Look for elements like <img>, <div>, <p>, <script> (without src), 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>.

  3. Use allowed rel values if a body placement is intentional: If you genuinely need a <link> in <body>, ensure it uses one of the permitted rel values (stylesheet, preload, prefetch, preconnect, dns-prefetch, modulepreload, pingback, prerender) or has an itemprop attribute.

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.

Help us improve our guides

Was this guide helpful?

Ready to validate your sites?
Start your free trial today.