HTML Guides for start tag
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
A <p> element cannot be placed inside a <noscript> tag within the <head> section.
According to the HTML specification, the <head> element must only contain metadata, such as <title>, <meta>, <link>, <script>, and <style>. The <noscript> element is allowed in <head>, but it must only contain elements that are valid in head, not flow content like <p>. The <p> (paragraph) tag is flow content meant for the <body>. For fallback content in <head>, only metadata elements are allowed.
Incorrect example:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
<noscript>
<p>JavaScript is disabled.</p>
</noscript>
</head>
<body>
</body>
</html>
Correct approaches:
-
Remove the <p> from <noscript> in <head>:
- If you must include fallback styles or links in case JavaScript is disabled, use only metadata tags.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
<noscript>
<link rel="stylesheet" href="no-js.css">
</noscript>
</head>
<body>
</body>
</html>
-
Place textual fallback content in the <body> instead:
- Moving the <noscript> block with flow content (such as <p>) to the body ensures validity.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<noscript>
<p>JavaScript is disabled.</p>
</noscript>
</body>
</html>
Remember: Do not use <p> (or any flow content) in <noscript> inside <head>. Use such content only in the body.
HTML follows strict nesting rules: elements must be closed in the reverse order they were opened, like a stack. When the validator encounters </X> but the current open element is Y, it means something has gone wrong in the document structure. The browser’s parser will attempt to recover from this mismatch, but the result may not reflect your intended layout or semantics.
There are several common causes for this error:
- Typos in tag names — for example, opening a <div> but closing it with </dvi>.
- Mismatched tags — opening one element but closing a different one, such as <strong> closed with </em>.
- Incorrect nesting order — overlapping elements where tags cross boundaries instead of being properly nested.
- Missing closing tags — a forgotten closing tag causes subsequent closing tags to be misaligned with the parser’s expectation.
This matters because improperly nested HTML can cause unpredictable rendering across browsers, break CSS styling, interfere with JavaScript DOM manipulation, and create accessibility problems for screen readers that rely on a well-formed document tree.
To fix this error, trace back from the reported line to find where the mismatch originates. Ensure that every opening tag has a corresponding closing tag with the exact same name, and that elements are closed in the correct order (last opened, first closed).
Examples
Typo in the closing tag
<!-- ❌ Wrong: closing tag is misspelled -->
<section>
<p>Hello world</p>
</secton>
<!-- ✅ Fixed: closing tag matches the opening tag -->
<section>
<p>Hello world</p>
</section>
Mismatched tags
<!-- ❌ Wrong: <strong> is closed with </em> -->
<p>This is <strong>important</em> text.</p>
<!-- ✅ Fixed: closing tag matches the opening tag -->
<p>This is <strong>important</strong> text.</p>
Incorrectly nested (overlapping) elements
<!-- ❌ Wrong: <b> and <i> overlap each other -->
<p><b>Bold <i>and italic</b> text</i></p>
The validator sees </b> when the current open element is <i>. Elements must nest completely inside one another without overlapping.
<!-- ✅ Fixed: elements are properly nested -->
<p><b>Bold <i>and italic</i></b><i> text</i></p>
Missing closing tag causing a cascade of errors
<!-- ❌ Wrong: missing </div> for the inner div -->
<div class="outer">
<div class="inner">
<p>Content</p>
</div>
Here the single </div> closes inner, leaving outer unclosed. If more HTML follows, subsequent closing tags will be misaligned, potentially producing this error further down in the document.
<!-- ✅ Fixed: both divs are properly closed -->
<div class="outer">
<div class="inner">
<p>Content</p>
</div>
</div>
Tips for debugging
- Work from the first error — in HTML validation, one early mistake can cascade into many subsequent errors. Fix the first reported mismatch and re-validate before tackling later errors.
- Use consistent indentation — properly indented code makes it much easier to spot where nesting goes wrong.
- Use an editor with bracket/tag matching — most code editors can highlight matching opening and closing tags, making mismatches immediately visible.
The HTML specification defines <a> elements as having a transparent content model, but with specific exceptions — most notably, they must not contain interactive content, which includes other <a> elements. This means you can never legally nest one link inside another, regardless of how deeply nested or how the markup is structured.
This error most commonly occurs for one of two reasons:
- A missing closing tag: You forgot to close a previous <a> element with </a>, so the browser (and the validator) considers the next <a> tag to be nested inside the still-open one.
- Intentionally nested links: You tried to place a link inside another link, perhaps to create a card component where both the card and an inner element are clickable.
Why this matters
- Unpredictable browser behavior: When browsers encounter nested <a> elements, they attempt to fix the invalid markup using error-recovery algorithms, but different browsers may handle it differently. This can lead to broken links, missing content, or unexpected DOM structures.
- Accessibility issues: Screen readers and other assistive technologies rely on a well-formed DOM. Nested links create confusing navigation — a user tabbing through links may encounter unexpected behavior or miss content entirely.
- Standards compliance: The WHATWG HTML specification explicitly states that <a> elements must not have interactive content descendants, including other <a> elements.
Examples
Missing closing tag (most common cause)
The most frequent trigger is simply forgetting to close an <a> tag. The validator sees the second <a> as being inside the first:
<!-- ❌ Bad: first <a> is never closed -->
<nav>
<a href="one.html">Page 1
<a href="two.html">Page 2</a>
</nav>
Add the missing </a> to fix it:
<!-- ✅ Good: both <a> elements are properly closed -->
<nav>
<a href="one.html">Page 1</a>
<a href="two.html">Page 2</a>
</nav>
Intentionally nested links
Sometimes developers try to nest links when building clickable card components:
<!-- ❌ Bad: <a> nested inside another <a> -->
<a href="/article" class="card">
<h2>Article Title</h2>
<p>A short description of the article.</p>
<a href="/author">Author Name</a>
</a>
There are several valid approaches to fix this. One common pattern is to make the card a non-link container and use CSS to stretch the primary link over the entire card:
<!-- ✅ Good: no nested links, card is still fully clickable -->
<div class="card">
<h2><a href="/article" class="card-link">Article Title</a></h2>
<p>A short description of the article.</p>
<a href="/author">Author Name</a>
</div>
.card {
position: relative;
}
.card-link::after {
content: "";
position: absolute;
inset: 0;
}
.card a:not(.card-link) {
position: relative;
z-index: 1;
}
This technique uses a pseudo-element to expand the primary link’s clickable area over the entire card, while the secondary link (Author Name) sits above it via z-index, remaining independently clickable.
Links wrapping block-level content
In HTML5, <a> elements can wrap block-level elements like <div> and <h2>, which is perfectly valid. Just make sure you don’t accidentally nest another <a> inside:
<!-- ✅ Good: <a> wrapping block content with no nested links -->
<a href="/article">
<div class="card">
<h2>Article Title</h2>
<p>A short description of the article.</p>
</div>
</a>
Quick checklist
- Search your HTML for every <a tag and verify it has a corresponding </a>.
- If you’re generating HTML dynamically (with a CMS, templating engine, or JavaScript), check that your template logic doesn’t produce unclosed or nested anchors.
- If you need multiple clickable areas within a single component, use the CSS pseudo-element overlay technique shown above instead of nesting links.
The HTML specification explicitly forbids nesting interactive content inside a <button> element. This means a <button> cannot contain another <button>, nor can it contain elements like <a>, <input>, <select>, <textarea>, or any other interactive element. The <button> element’s content model allows phrasing content, but specifically excludes interactive content.
The most common cause of this error is a missing </button> closing tag. When you forget to close a button, the parser considers everything that follows — including the next <button> start tag — as being inside the first button. This creates an invalid nesting situation even though you likely intended the buttons to be siblings.
This matters for several reasons:
- Accessibility: Screen readers and assistive technologies rely on proper document structure. A button nested inside another button creates a confusing interaction model — which button does the user activate when they click or press Enter?
- Browser behavior: Browsers handle this invalid markup inconsistently. Some may ignore the inner button, while others may attempt error recovery in unpredictable ways, leading to broken functionality.
- Standards compliance: Invalid HTML can interfere with JavaScript event handling, CSS styling, and overall page reliability.
Examples
Missing closing tag (triggers the error)
<button>Submit
<button>Cancel</button>
Here, the first <button> is never closed, so the parser sees the second <button> as being nested inside it.
Intentionally nested buttons (triggers the error)
<button class="card">
<span>Select this plan</span>
<button class="details">More info</button>
</button>
Even if this nesting is intentional, it is invalid HTML. A <button> cannot contain another <button>.
Fix: Close each button properly
<button>Submit</button>
<button>Cancel</button>
Adding the missing </button> tag makes the two buttons proper siblings.
Fix: Restructure nested interactive elements
If you need a clickable card with an additional action inside it, separate the interactive elements rather than nesting them:
<div class="card">
<button class="select">Select this plan</button>
<button class="details">More info</button>
</div>
Fix: Use non-interactive elements for styling purposes
If the inner element was only meant for visual grouping, use a <span> or other phrasing element instead of a <button>:
<button class="card">
<span class="label">Select this plan</span>
<span class="sublabel">Best value</span>
</button>
This keeps a single interactive <button> while using non-interactive <span> elements for internal structure and styling.
The Document Type Declaration (commonly called the “doctype”) tells browsers which version and rules of HTML the document follows. In modern HTML5, the doctype is simply <!DOCTYPE html>. It must be the very first thing in the document — before the <html> tag, before any whitespace-generating content, and before any other elements. The only thing permitted before it is an optional BOM (byte order mark) or whitespace characters.
Without a doctype, browsers fall back to quirks mode, a legacy rendering mode that emulates old, inconsistent browser behavior. In quirks mode, the CSS box model, table sizing, font inheritance, and many other layout behaviors work differently than in standards mode. This can cause your page to render inconsistently across browsers and lead to hard-to-debug visual issues. Including the doctype ensures the browser uses standards mode, giving you predictable, spec-compliant rendering.
This error commonly occurs for a few reasons:
- The doctype was simply forgotten or accidentally deleted.
- There is content before the doctype, such as an XML declaration (<?xml version="1.0"?>), a comment, or a server-side include.
- The doctype is misspelled or uses an older, incorrect format.
- The file contains a BOM or invisible characters before the doctype that shift it out of position (though the validator may report this differently).
The doctype declaration is case-insensitive — <!DOCTYPE html>, <!doctype html>, and <!Doctype Html> are all valid — but the lowercase-uppercase convention <!DOCTYPE html> is the most widely used.
Examples
❌ Missing doctype entirely
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
The validator sees the <html> start tag but no doctype has appeared yet, triggering the error.
❌ Content before the doctype
<!-- This is my website -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
Even an HTML comment placed before the doctype can trigger this warning, because the parser encounters non-doctype content first.
❌ Old or malformed doctype
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
While older doctypes like HTML 4.01 may not always produce this exact error, they can trigger related warnings. The HTML5 doctype is the recommended standard for all new documents.
✅ Correct: doctype as the first line
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
The <!DOCTYPE html> appears first, followed by the <html> tag with a lang attribute, a <head> with a required <title>, and the <body>. This is a minimal, fully valid HTML5 document.
✅ Correct: fragment with doctype added
If you were previously only writing a fragment like <div><p>Hello</p></div>, wrap it in a proper document structure:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Fragment</title>
</head>
<body>
<div>
<p>Hello</p>
</div>
</body>
</html>
Always ensure <!DOCTYPE html> is the absolute first thing in every HTML file you create. It’s a one-line addition that guarantees standards-mode rendering and keeps your document valid.
A stray <br> happens when the <br> element, which is phrasing content, is placed in contexts that only allow specific children. Common mistakes include putting <br> directly inside <ul>, <ol>, <table>, <tr>, or outside <body>, and inserting it between block-level siblings to add spacing instead of using CSS. The validator flags this because it violates the HTML content model.
This matters for standards compliance, predictable rendering, and accessibility. Screen readers and assistive tech rely on correct structure (lists made of li, tables built from tr/td, sections within body). Misplaced <br> can produce confusing reading orders and inconsistent layout across browsers.
How to fix:
- Keep <br> only where phrasing content is allowed (typically inside text-flowing elements like p, span, li, td, caption).
- For spacing between blocks, use CSS margins instead of <br>.
- For lists, use proper li items; for tables, place text inside td/th; for forms, use grouping and CSS.
- Ensure no <br> appears outside <body> or inside elements that have restricted content models (ul, ol, table, tr, thead, tbody, tfoot, colgroup, select, dl directly, etc.).
- If a line break is purely presentational across viewports, consider CSS (display:block, white-space) instead of <br>.
Examples
Valid use inside phrasing content
<p>
First line.<br>
Second line.
</p>
Invalid: <br> directly inside a list (triggers the error)
<ul>
<br>
<li>Item 1</li>
<li>Item 2</li>
</ul>
Fix: remove the stray <br>; use list items only
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
Invalid: <br> outside <body> (triggers the error)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Stray br Tag Example</title>
</head>
<br>
<body>
Content here.
</body>
</html>
Fix: move <br> inside the body (or use CSS if only spacing is needed)
<!DOCTYPE html>
<html lang="en">
<head>
<title>No Stray br Tag</title>
</head>
<body>
Content here.<br>
New line in body.
</body>
</html>
Invalid: <br> as a child of <table> (triggers the error)
<table>
<br>
<tr>
<td>A</td>
<td>B</td>
</tr>
</table>
Fix: use proper table rows and cells; place text inside cells
<table>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>More A</td>
<td>More B</td>
</tr>
</table>
Invalid: using <br> for spacing between blocks (not allowed between siblings)
<div>Section A</div>
<br>
<div>Section B</div>
Fix: use CSS margins for spacing
<!DOCTYPE html>
<html lang="en">
<head>
<title>Spacing with CSS</title>
<style>
.block { margin-bottom: 1rem; }
</style>
</head>
<body>
<div class="block">Section A</div>
<div>Section B</div>
</body>
</html>
Valid alternatives where a break is needed in phrasing context
<li>
Address: 123 Main St.<br>
Suite 400
</li>
Tips:
- Use exactly <br> (no closing tag needed) and do not self-close as XML (<br />) unless your tooling requires it; both parse in HTML, but stick to HTML style for consistency.
- If you see multiple “stray start tag ‘br’” errors, check parent containers: fixing the first invalid parent often resolves many subsequent errors.
A <div> tag appears where the HTML structure does not expect it, often due to incorrect nesting or missing closing tags.
HTML elements must be properly nested and closed according to the specifications outlined by the HTML standard. A stray start tag usually occurs when a block-level element like <div> is used in a context where only phrasing (inline) content is permitted, or if required closing tags (such as </li>, </tr>, or </td>) are missing, causing the parser to be out of sync.
Incorrect Example: div after closing the html tag
<!DOCTYPE html>
<html lang="">
<head>
<title>Test</title>
</head>
<body>
<p></p>
</body>
</html>
<div>
some extra content
</div>
In the above, the <div> at the bottom is not valid because it appears after closing the html tag.
Always close elements properly and place block-level elements like <div> only inside appropriate containers. If your issue occurs elsewhere, look for missing closing tags or incorrect placement of the <div> relative to tables, lists, or other structural elements.
The <head> element is the container for document metadata — things like the <title>, <meta> tags, <link> elements, and <script> references. According to the HTML specification, the <head> must be the first child element of <html> and must appear exactly once. When the browser’s parser encounters a second <head> tag, or a <head> tag after the <body> has already opened, it treats it as a “stray” start tag because it violates the expected document structure.
This issue commonly arises in several situations:
- Duplicate <head> sections — often caused by copy-paste errors, template includes, or server-side rendering that injects a second <head> block.
- <head> placed inside <body> — this can happen when restructuring a page or when a component or partial template incorrectly includes its own <head>.
- Missing or misplaced closing tags — if you forget to close the <head> with </head> or accidentally close <html> early, subsequent tags may end up in unexpected positions.
This matters because browsers handle stray <head> tags inconsistently. Most modern browsers will silently ignore a second <head> and attempt to process its children as if they were part of <body>, which means your metadata (like <meta> charset declarations, stylesheets, or scripts) may not be recognized properly. This can lead to broken styling, encoding issues, missing SEO metadata, and unpredictable behavior across different browsers.
Examples
Duplicate <head> sections
A common mistake is having two <head> blocks in the same document:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<head>
<meta name="description" content="My description">
</head>
<body>
<p>Hello world</p>
</body>
</html>
The second <head> triggers the stray start tag error. Merge everything into a single <head>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<meta name="description" content="My description">
</head>
<body>
<p>Hello world</p>
</body>
</html>
<head> placed inside <body>
This often happens when a template partial or component includes its own <head>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<head>
<link rel="stylesheet" href="extra.css">
</head>
<p>Hello world</p>
</body>
</html>
Move the metadata into the existing <head> section:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<link rel="stylesheet" href="extra.css">
</head>
<body>
<p>Hello world</p>
</body>
</html>
<head> appearing after <body>
Sometimes a <head> ends up after the closing </body> tag, particularly in dynamically assembled pages:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
<head>
<meta charset="utf-8">
</head>
</html>
Again, the fix is to consolidate everything into the single, correctly placed <head>:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Tip for template-based systems
If you use a templating engine, static site generator, or CMS, check that only your base layout defines the <head> element. Partials and components should inject content into the existing <head> using the templating system’s block or slot mechanism, rather than wrapping their metadata in a new <head> tag. Search the final rendered HTML output for all occurrences of <head to verify there is only one.
The <html> element serves as the root of an HTML document. According to the HTML specification, there can only be one root element, and it must contain exactly one <head> element followed by one <body> element. When the browser’s parser encounters a second <html> start tag, it doesn’t know what to do with it — the tag is considered “stray” because it appears in a context where it is not expected or allowed.
This error typically occurs in a few common scenarios:
- Copy-paste mistakes — When copying HTML from another file, you may accidentally paste an entire document (including its <html> tag) inside an existing document.
- Template or include errors — Server-side includes, template engines, or component-based frameworks may inject a full HTML document structure (with its own <html> tag) into a page that already has one.
- Merging files incorrectly — Combining multiple HTML files without removing the structural tags from the inner files.
- Accidental duplication — Simply having a duplicate <html> tag due to a typo or editing oversight.
A stray <html> tag signals a malformed document structure. Browsers will attempt to recover by ignoring the duplicate tag, but the intent behind the markup becomes ambiguous. This can lead to unpredictable rendering, broken styles, or scripts that fail to target elements correctly. It also harms accessibility, as screen readers and other assistive technologies rely on a well-formed document tree to interpret content.
To fix this issue, search your HTML source for all instances of <html and ensure only one exists — at the very top of the document, right after the <!DOCTYPE html> declaration. If you find a second one, remove it along with any corresponding duplicate </html>, <head>, </head>, <body>, and </body> tags that came with it, keeping only the actual content you need.
Examples
Incorrect: Duplicate <html> tag from pasted content
This example shows a full HTML document accidentally embedded inside another, which produces the stray start tag error:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome</h1>
<!-- Accidentally pasted another full document -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Other Page</title>
</head>
<body>
<p>This content was pasted from another file.</p>
</body>
</html>
</body>
</html>
Correct: Single <html> element with merged content
Remove the duplicate document structure and keep only the content you need:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Welcome</h1>
<!-- Only the relevant content from the other file -->
<p>This content was pasted from another file.</p>
</body>
</html>
Incorrect: Accidental duplicate <html> tag
Sometimes the duplication is a simple typo:
<!DOCTYPE html>
<html lang="en">
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Correct: Single <html> tag
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Checking template-based projects
If you use a templating system (e.g., PHP includes, Jinja2, Handlebars, or similar), make sure your partials and includes contain only content fragments — not full document structures. For example, an included partial should look like this:
<!-- partial: sidebar.html — no <html>, <head>, or <body> tags -->
<aside>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
</aside>
The key rule is simple: every HTML document must have exactly one <html> element. If the validator reports a stray start tag, trace it back to its source — whether that’s a copy-paste error, a template include, or a simple duplication — and remove it.
A stray start tag “link” error occurs when a <link> element appears outside the <head> section, for example after the document’s closing </html> tag.
The <link> element is used to reference external resources like stylesheets and must appear inside the document’s <head> section, before </head>.
Valid usage example:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Link Tag Example</title>
<link rel="stylesheet" href="css/app.css">
</head>
<body>
</body>
</html>
In this example, the <link> tag is correctly placed within the <head> element.
The “stray start tag” terminology means the HTML parser encountered a <noscript> element in a location where no element should exist. This typically happens when the tag appears between </head> and <body>, after </body>, after </html>, or when a preceding markup error has caused the parser to close the <body> prematurely, leaving the <noscript> orphaned outside any valid container.
According to the WHATWG HTML living standard, <noscript> is permitted in two contexts: inside <head> (where it can only contain <link>, <style>, and <meta> elements) and inside <body> as a flow content element (where it can contain any content normally allowed in its parent). When found anywhere else, the parser treats it as a “stray” tag because it has no valid parent to attach to.
This matters because stray elements lead to unpredictable behavior across browsers. While most browsers attempt error recovery, the resulting DOM may not match your intentions. The fallback content inside a stray <noscript> may be silently discarded or rendered incorrectly, defeating its purpose of providing an accessible experience for users without JavaScript.
A common cause is markup generated by third-party tools like analytics platforms or tag managers. These snippets often instruct you to paste a <noscript> tag “immediately after the opening <body> tag,” but if pasted in the wrong location — or if a templating system places it outside <body> — the error occurs.
Another frequent cause is unclosed elements earlier in the document. If a tag above the <noscript> is malformed, the parser may implicitly close the <body>, making subsequent elements stray. In these cases, fixing the earlier error resolves the <noscript> issue as well.
How to fix it
- Ensure <noscript> is inside <head> or <body> — never between them, before <html>, or after </html>.
- When inside <head>, only include <link>, <style>, or <meta> elements within it.
- When inside <body>, use it like any other block-level element — it can contain paragraphs, divs, images, etc.
- Check for unclosed tags above the <noscript> that might cause the parser to prematurely exit <body>.
Examples
Stray <noscript> after closing </body>
This is the most common scenario, often caused by pasting a tracking snippet in the wrong place:
<!-- ❌ Incorrect: noscript is outside body -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
</body>
<noscript>
<p>Please enable JavaScript.</p>
</noscript>
</html>
Move it inside <body>:
<!-- ✅ Correct: noscript is inside body -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello</h1>
<noscript>
<p>Please enable JavaScript.</p>
</noscript>
</body>
</html>
Stray <noscript> between </head> and <body>
<!-- ❌ Incorrect: noscript is between head and body -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<noscript>
<iframe src="https://example.com/ns.html"></iframe>
</noscript>
<body>
<p>Content here.</p>
</body>
</html>
Place it at the top of <body> instead:
<!-- ✅ Correct: noscript is inside body -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<noscript>
<iframe src="https://example.com/ns.html" title="Tracking fallback"></iframe>
</noscript>
<p>Content here.</p>
</body>
</html>
Using <noscript> inside <head>
When placed in <head>, <noscript> can only contain <link>, <style>, or <meta> elements — not block content like <p> or <iframe>:
<!-- ❌ Incorrect: p is not allowed in noscript inside head -->
<head>
<title>My Page</title>
<noscript>
<p>Enable JavaScript!</p>
</noscript>
</head>
Either use only permitted elements in <head>, or move the <noscript> to <body>:
<!-- ✅ Correct: style is allowed in noscript inside head -->
<head>
<title>My Page</title>
<noscript>
<style>
.js-only { display: none; }
.nojs-message { display: block; }
</style>
</noscript>
</head>
Stray <noscript> caused by an unclosed element
Sometimes the real problem is an earlier unclosed tag. The parser implicitly closes <body>, making the <noscript> stray:
<!-- ❌ Incorrect: unclosed <div> causes parser confusion -->
<body>
<div>
<p>Some content</p>
<!-- missing </div> causes cascade of errors -->
<noscript>
<p>JavaScript is required.</p>
</noscript>
</body>
Fix the unclosed element, and the <noscript> error resolves:
<!-- ✅ Correct: div is properly closed -->
<body>
<div>
<p>Some content</p>
</div>
<noscript>
<p>JavaScript is required.</p>
</noscript>
</body>
In a valid HTML document, all content must reside within the <html> element, and specifically within either <head> or <body>. The HTML parser expects a well-defined structure: <!DOCTYPE html>, then <html>, containing <head> and <body>. When a <script> tag appears outside this hierarchy — for example, after the closing </html> tag — the validator reports it as a “stray start tag” because it has no valid parent in the document tree.
This is a common issue that arises in a few ways. Sometimes developers accidentally place a script after </body> or </html>, thinking it will still execute. Other times, template systems or CMS platforms inject scripts at the end of the output without ensuring they’re inside <body>. While browsers are forgiving and will typically still execute the script, relying on this error-recovery behavior leads to non-standard markup and unpredictable DOM placement.
Why this matters
- Standards compliance: The HTML specification requires all elements to be properly nested within the document structure. A <script> outside <html> violates this requirement.
- Predictable DOM: When a browser encounters a stray <script>, it must use error recovery to determine where to place it in the DOM. Different browsers may handle this differently, leading to inconsistencies.
- Maintainability: Invalid markup can cause confusing debugging scenarios, especially when JavaScript relies on DOM structure or ordering.
How to fix it
Move the <script> element inside either <head> or <body>:
- Place it in <head> if the script needs to load before the page content renders (configuration, analytics setup, etc.). Consider using the defer or async attribute for external scripts to avoid blocking rendering.
- Place it at the end of <body> (just before </body>) if the script interacts with DOM elements, which is a common and recommended pattern.
Examples
Incorrect: script after closing </html> tag
This triggers the “Stray start tag script” error because the <script> is outside the document structure entirely.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
<script>
console.log("This is stray!");
</script>
Incorrect: script between </head> and <body>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<script>
console.log("Misplaced script");
</script>
<body>
<p>Hello world</p>
</body>
</html>
Correct: script in the <head>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<script>
console.log("Hello from the head");
</script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
Correct: script at the end of <body>
This is the most common and recommended placement for scripts that interact with the page.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
<script>
console.log("Hello from the body");
</script>
</body>
</html>
Correct: external script with defer in <head>
Using defer lets you place the script in <head> while ensuring it executes after the DOM is fully parsed, giving you the best of both worlds.
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<script src="app.js" defer></script>
</head>
<body>
<p>Hello world</p>
</body>
</html>
The word “stray” in this error message means the validator encountered a start tag in a place where no element of that kind is allowed according to the HTML specification. The <section> element is flow content, so it must appear inside the <body> element (or inside another element that accepts flow content, such as <main>, <article>, <div>, etc.). When the validator sees <section> somewhere it can’t legally exist, it flags it as “stray.”
There are several common causes for this error:
- Content placed after </body> or </html>: The most frequent cause. Extra markup exists beyond the closing tags of the document body.
- Premature closing of the <body>: An extra or misplaced </body> tag earlier in the document causes the browser to consider the body closed, making any subsequent <section> stray.
- Nesting inside elements that don’t accept flow content: Placing <section> directly inside a <p>, <span>, <a>, or other phrasing-content-only element. Since these elements can’t contain block-level flow content, the browser implicitly closes the parent, leaving <section> in an invalid position.
- Malformed or unclosed tags: Earlier syntax errors — like a missing closing > on a tag — can shift the parser’s understanding of the document tree, causing downstream elements to appear stray.
This matters because browsers use error recovery when they encounter stray elements, and different browsers may handle the recovery differently. Your content could end up outside the visible document, be rendered inconsistently, or cause accessibility tools to misinterpret the page structure. Fixing this error ensures predictable rendering and a well-formed document.
Examples
Stray <section> after the closing </body> tag
This is the most common scenario. Content placed after </body> has nowhere valid to go:
<!-- ❌ Incorrect: section appears after </body> -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<h1>Welcome</h1>
<p>Some content.</p>
</body>
<section>
<h2>About</h2>
<p>This section is stray.</p>
</section>
</html>
Move the <section> inside the <body>:
<!-- ✅ Correct: section is inside <body> -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<h1>Welcome</h1>
<p>Some content.</p>
<section>
<h2>About</h2>
<p>This section is properly placed.</p>
</section>
</body>
</html>
Extra </body> tag causing a premature close
A duplicate closing tag can trick the parser into ending the body early:
<!-- ❌ Incorrect: extra </body> causes section to become stray -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<div>
<p>Main content.</p>
<!-- accidental extra closing tag -->
</div>
<section>
<h2>Updates</h2>
<p>This is now stray.</p>
</section>
</body>
</html>
Remove the extra </body> tag:
<!-- ✅ Correct: single </body> at the end -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example</title>
</head>
<body>
<div>
<p>Main content.</p>
</div>
<section>
<h2>Updates</h2>
<p>This is correctly placed now.</p>
</section>
</body>
</html>
Nesting <section> inside a <p> element
The <p> element only accepts phrasing content. When the parser encounters a <section> inside a <p>, it implicitly closes the <p> first, which can leave the <section> in an unexpected position:
<!-- ❌ Incorrect: section nested inside a paragraph -->
<p>
Introduction text.
<section>
<h2>Details</h2>
<p>More info here.</p>
</section>
</p>
Separate the paragraph and section into siblings:
<!-- ✅ Correct: section is a sibling, not a child of <p> -->
<p>Introduction text.</p>
<section>
<h2>Details</h2>
<p>More info here.</p>
</section>
Unclosed tag causing downstream errors
A missing closing angle bracket on an earlier element can corrupt the parser’s view of the entire document tree:
<!-- ❌ Incorrect: missing > on the </div causes parsing issues -->
<body>
<div>
<p>Content here.</p>
</div
<section>
<h2>Topics</h2>
<p>This may be flagged as stray.</p>
</section>
</body>
Fix the malformed tag:
<!-- ✅ Correct: properly closed </div> -->
<body>
<div>
<p>Content here.</p>
</div>
<section>
<h2>Topics</h2>
<p>No longer stray.</p>
</section>
</body>
How to debug this issue
- Check the line number reported by the validator and look at what comes before the <section> tag — the problem is usually above it, not at the <section> itself.
- Search for extra closing tags like </body>, </html>, or </div> that might prematurely close a container.
- Verify parent elements — make sure <section> isn’t nested inside <p>, <span>, <a>, <button>, or other elements that only accept phrasing content.
- Use proper indentation to make the document hierarchy visually clear. Misplaced tags are much easier to spot in well-formatted code.
- Revalidate after each fix, since correcting one stray tag error often resolves multiple related warnings.
The “Stray start tag style“ error occurs when the HTML parser encounters a <style> element somewhere it doesn’t belong according to the HTML specification. The most common causes are:
- A <style> element placed after the closing </body> tag or after the closing </html> tag.
- A <style> element accidentally placed inside an element like <p>, <span>, or <a> that only accepts phrasing content and not <style> in that context.
- A <style> element appearing in the <body> without being a valid child in that context (though the HTML living standard does allow <style> in the <body> in certain conditions).
According to the WHATWG HTML living standard, the <style> element is primarily expected inside the <head> section. While the spec does technically allow <style> in the <body> where metadata content is expected (such as within a <noscript> element that is a child of <head>), placing it in the <head> is the most reliable and universally valid approach.
When a <style> tag appears after </body> or </html>, the browser’s error-recovery behavior kicks in. Browsers will still try to apply the styles, but you’re relying on undefined recovery behavior rather than the specification. This can lead to inconsistent rendering, makes the document harder to maintain, and signals structural problems in your HTML.
This issue commonly arises when content management systems, JavaScript frameworks, or copy-paste mistakes inject styles at the end of a document. It can also happen when template includes or server-side rendering place <style> blocks in unexpected locations.
To fix this issue, move the <style> element into the <head> section. Alternatively, consider moving the CSS into an external stylesheet linked via a <link> element, which is generally the preferred approach for maintainability and caching.
Examples
Incorrect: <style> after the closing </body> tag
This is the most common scenario that triggers the error. The <style> element is “stray” because it appears outside the <body> and <head>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
<style>
p {
color: green;
}
</style>
</html>
Incorrect: <style> after the closing </html> tag
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<p>Hello world</p>
</body>
</html>
<style>
p {
color: green;
}
</style>
Incorrect: <style> nested inside a <p> element
The <p> element only accepts phrasing content, so a <style> element here may trigger the stray tag error:
<p>
<style>
.highlight { color: red; }
</style>
Some highlighted text.
</p>
Correct: <style> inside the <head>
Move all <style> elements into the <head> section:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<style>
p {
color: green;
}
.highlight {
color: red;
}
</style>
</head>
<body>
<p>Hello world</p>
<p class="highlight">Important text.</p>
</body>
</html>
Correct: using an external stylesheet instead
For better separation of concerns, caching, and maintainability, use an external stylesheet:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<p>Hello world</p>
</body>
</html>
If you have multiple <style> blocks scattered throughout your document, consolidate them all into a single <style> element in the <head>, or better yet, move them into an external .css file. This ensures valid HTML, predictable rendering across browsers, and cleaner document structure.
A td (table cell) start tag must be placed inside a tr (table row) within a table.
The td element represents a cell of a table that contains data. According to HTML specifications, a td must be a child of a tr, which in turn must be a child of a table. Placing a td directly outside a tr or outside a table is invalid and causes the “stray start tag ‘td’” error in the W3C Validator.
Incorrect usage:
<table>
<td>Cell data</td>
</table>
In the above example, the td is not inside a tr.
Correct usage:
<table>
<tr>
<td>Cell data</td>
</tr>
</table>
Here, the td is nested inside a tr, which is correctly within a table. This will resolve the validation error.
Ready to validate your sites?
Start your free trial today.