HTML Guides for name
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.
This error is misleading at first glance because the <meta> tag in question is often perfectly well-formed. The real problem is usually above the <meta> tag — an element that doesn’t belong in <head> (such as <img>, <div>, <p>, or other flow content) has been placed there. When the HTML parser encounters such an element inside <head>, it implicitly closes the <head> and opens the <body>. From that point on, any subsequent <meta> tags are now technically inside the <body>, where the name attribute on <meta> is not permitted.
In other cases, the error can also occur when a <meta name="..."> tag is explicitly placed inside <body>, or when a typo or malformed tag earlier in the document breaks the expected document structure.
This matters for several reasons. Search engines and social media platforms rely on <meta> tags being in the <head> to extract page descriptions, Open Graph data, and other metadata. If the document structure is broken and <meta> tags end up in the <body>, this metadata may be ignored entirely. Additionally, elements like <img> inside <head> won’t render as expected, and the overall document structure will be invalid, potentially causing unpredictable behavior across browsers.
How to fix it
- Look above the flagged <meta> tag. Find any element in the <head> that doesn’t belong there — common culprits include <img>, <div>, <span>, <p>, <a>, or <section>.
- Move the offending element into the <body> where it belongs.
- If the <meta> tag itself is in the <body>, move it into the <head>.
- Check for malformed tags above the <meta> — an unclosed tag or a typo can break the parser’s understanding of the document structure.
Only certain elements are allowed inside <head>: <title>, <meta>, <link>, <style>, <script>, <noscript>, <base>, and <template>.
Examples
An invalid element in <head> breaks the context
The <img> tag is not allowed inside <head>. The parser implicitly closes <head> when it encounters it, so the <meta> tag that follows ends up in <body>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<img src="photo.jpg" alt="A smiling cat">
<meta name="description" content="A page about cats">
</head>
<body>
<p>Welcome!</p>
</body>
</html>
Move the <img> into the <body> to fix the issue:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<meta name="description" content="A page about cats">
</head>
<body>
<img src="photo.jpg" alt="A smiling cat">
<p>Welcome!</p>
</body>
</html>
A <meta> tag accidentally placed in <body>
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
</head>
<body>
<meta name="author" content="Jane Doe">
<p>Hello world</p>
</body>
</html>
Move the <meta> tag into <head>:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<meta name="author" content="Jane Doe">
</head>
<body>
<p>Hello world</p>
</body>
</html>
A malformed tag disrupts the <head>
A missing closing > on a <link> tag can confuse the parser, causing subsequent elements to be misinterpreted:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<link rel="stylesheet" href="style.css"
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Content</p>
</body>
</html>
Close the <link> tag properly:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Page</title>
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Content</p>
</body>
</html>
The name attribute on <a> elements was historically used to create named anchors — fragment targets that could be linked to with href="#anchorName". In modern HTML (the WHATWG living standard), the name attribute on <a> is considered obsolete for this purpose. The id attribute is now the standard way to create fragment targets, and it can be placed on any element, not just <a> tags.
Regardless of whether you use name or id, the value must be a non-empty string. The W3C validator enforces this rule because an empty identifier serves no functional purpose — it cannot be referenced by a fragment link, it cannot be targeted by JavaScript, and it creates invalid markup. Browsers may silently ignore it, but it pollutes the DOM and signals a likely mistake in the code.
Empty name attributes often appear in content migrated from older CMS platforms or WYSIWYG editors that inserted placeholder anchors like <a name=""></a>. They can also result from templating systems where a variable intended to populate the attribute resolved to an empty string.
Why this matters
- Standards compliance: Both the WHATWG HTML living standard and the W3C HTML specification require that identifier-like attributes (id, name) must not be empty strings.
- Accessibility: Screen readers and assistive technologies may attempt to process named anchors. Empty identifiers create noise without providing any navigational value.
- Functionality: An empty name or id cannot be used as a fragment target, so the element is effectively useless as a link destination.
How to fix it
- Remove the element entirely if the empty anchor serves no purpose — this is the most common fix.
- Replace name with id and provide a meaningful, non-empty value if you need a fragment target.
- Move the id to a nearby semantic element instead of using a standalone empty <a> tag. For example, place the id directly on a heading, section, or paragraph.
- Ensure uniqueness — every id value in a document must be unique.
Examples
❌ Empty name attribute triggers the error
<a name=""></a>
<h2>Introduction</h2>
<p>Welcome to the guide.</p>
❌ Empty name generated by a template
<a name=""></a>
<p>This anchor was meant to be a target but the value is missing.</p>
<a href="#">Jump to section</a>
✅ Remove the empty anchor if it’s unnecessary
<h2>Introduction</h2>
<p>Welcome to the guide.</p>
✅ Use id on the target element directly
<h2 id="introduction">Introduction</h2>
<p>Welcome to the guide.</p>
<!-- Link to the section from elsewhere -->
<a href="#introduction">Go to Introduction</a>
✅ Use id on a standalone anchor if needed
If you need a precise anchor point that doesn’t correspond to an existing element, use an <a> tag with a valid, non-empty id:
<a id="section-start"></a>
<p>This paragraph follows the anchor point.</p>
<a href="#section-start">Jump to section start</a>
✅ Migrate legacy name to id
If your existing code uses the obsolete name attribute with a valid value, update it to use id instead:
<!-- Before (obsolete but was valid in HTML4) -->
<a name="contact"></a>
<!-- After (modern HTML) -->
<a id="contact"></a>
<!-- Even better: put the id on a semantic element -->
<h2 id="contact">Contact Us</h2>
The HTML specification requires that if the name attribute is used on a <form> element, its value must be a non-empty string. An empty name="" attribute serves no practical purpose — it doesn’t register the form in the document.forms named collection, and it can’t be used as a valid reference in scripts. The W3C validator flags this as an error because it violates the content model defined in the WHATWG HTML Living Standard.
The name attribute on a form is primarily used to access the form programmatically through document.forms["formName"]. When the value is empty, this lookup mechanism doesn’t work, so the attribute becomes meaningless. This is different from the id attribute, which also identifies elements but participates in fragment navigation and CSS targeting. The name attribute on <form> is specifically for the legacy document.forms named getter interface.
It’s worth noting that the name attribute value on a form must not equal an empty string, and it should be unique among the form elements in the forms collection. While duplicate names won’t cause a validation error, they can lead to unexpected behavior when accessing forms by name in JavaScript.
How to fix
You have two options:
- Remove the attribute entirely. If you’re not referencing the form by name in JavaScript, the name attribute is unnecessary. You can use id instead for CSS or JavaScript targeting.
- Provide a meaningful, non-empty value. If you need to reference the form through document.forms, give it a descriptive name that reflects its purpose.
Examples
❌ Invalid: empty name attribute
<form name="">
<label for="email">Email</label>
<input type="email" id="email" name="email">
<button type="submit">Subscribe</button>
</form>
This triggers the validator error because the name attribute is present but has an empty string value.
✅ Fixed: attribute removed
<form>
<label for="email">Email</label>
<input type="email" id="email" name="email">
<button type="submit">Subscribe</button>
</form>
If you don’t need to reference the form by name, simply remove the attribute.
✅ Fixed: meaningful name provided
<form name="subscriptionForm">
<label for="email">Email</label>
<input type="email" id="email" name="email">
<button type="submit">Subscribe</button>
</form>
With a non-empty name, you can now access the form in JavaScript using document.forms["subscriptionForm"] or document.forms.subscriptionForm.
✅ Alternative: using id instead
<form id="subscription-form">
<label for="email">Email</label>
<input type="email" id="email" name="email">
<button type="submit">Subscribe</button>
</form>
In modern development, using id with document.getElementById() or document.querySelector() is often preferred over the name attribute for form identification. The name attribute on <form> is a legacy feature that remains valid but isn’t required for most use cases.
The name attribute on an <input> element identifies the form control’s data when the form is submitted. It acts as the key in the key-value pair sent to the server (e.g., email=user@example.com). When you set name="", the attribute is present but contains an empty string, which the HTML specification considers an invalid value. An empty name means the input’s data will be excluded from the form’s submission payload in most browsers, making it functionally useless for form processing.
This issue matters for several reasons:
- Form functionality: Inputs with empty names are typically omitted from form data, so the server never receives the user’s input.
- Standards compliance: The HTML specification requires that if the name attribute is present, its value must not be empty.
- JavaScript references: An empty name makes it difficult to reference the element using methods like document.getElementsByName() or FormData.
- Accessibility: Screen readers and assistive technologies may use the name attribute to help identify form controls, and an empty value provides no useful information.
Note that the name attribute is not technically required on every <input> element — it’s perfectly valid to omit it entirely. For example, inputs used purely for client-side JavaScript interactions without form submission don’t need a name. The error specifically arises when the attribute is present but set to an empty string.
To fix the issue, either assign a meaningful name that describes the data the input collects, or remove the name attribute altogether if the input isn’t part of a form submission.
Examples
❌ Empty name attribute triggers the error
<form action="/submit" method="post">
<label for="email">Email:</label>
<input type="email" id="email" name="">
<button type="submit">Submit</button>
</form>
✅ Providing a meaningful name value
<form action="/submit" method="post">
<label for="email">Email:</label>
<input type="email" id="email" name="email">
<button type="submit">Submit</button>
</form>
✅ Removing name when the input isn’t submitted
If the input is only used for client-side interaction and doesn’t need to be part of form data, simply omit the attribute:
<label for="search">Filter results:</label>
<input type="text" id="search">
❌ Multiple inputs with empty names
This pattern sometimes appears when inputs are generated dynamically with placeholder attributes:
<form action="/register" method="post">
<input type="text" name="">
<input type="password" name="">
<button type="submit">Register</button>
</form>
✅ Each input gets a descriptive name
<form action="/register" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<button type="submit">Register</button>
</form>
In HTML, the name attribute on an <iframe> defines a browsing context name. This name can be referenced by other elements — for example, a link with target="my-frame" will open its URL inside the <iframe> whose name is "my-frame". The HTML specification reserves all browsing context names that start with an underscore for special keywords:
- _self — the current browsing context
- _blank — a new browsing context
- _parent — the parent browsing context
- _top — the topmost browsing context
Because the underscore prefix is reserved for these (and potentially future) keywords, the spec requires that any custom browsing context name must not begin with _. Setting name="_example" or name="_myFrame" on an <iframe> is invalid HTML, even though those exact strings aren’t currently defined keywords. Browsers may handle these inconsistently — some might ignore the name entirely, while others could treat it as one of the reserved keywords, leading to unexpected navigation behavior.
This matters for several reasons:
- Standards compliance: The WHATWG HTML living standard explicitly states that a valid browsing context name must not start with an underscore character.
- Predictable behavior: Using a reserved prefix can cause links or forms targeting that <iframe> to navigate in unintended ways (e.g., opening in a new tab instead of within the frame).
- Future-proofing: New underscore-prefixed keywords could be added to the spec, which might break pages that use custom names starting with _.
To fix the issue, simply rename the name attribute value so it doesn’t start with an underscore. You can use underscores elsewhere in the name — just not as the first character.
Examples
❌ Invalid: name starts with an underscore
<iframe src="https://example.com" name="_example"></iframe>
<a href="https://example.com/page" target="_example">Open in frame</a>
The name _example starts with an underscore, which makes it invalid. A browser might interpret _example unpredictably or ignore the name entirely when used as a target.
✅ Fixed: underscore removed from the start
<iframe src="https://example.com" name="example"></iframe>
<a href="https://example.com/page" target="example">Open in frame</a>
✅ Fixed: underscore used elsewhere in the name
<iframe src="https://example.com" name="my_example"></iframe>
<a href="https://example.com/page" target="my_example">Open in frame</a>
Underscores are perfectly fine as long as they aren’t the first character.
❌ Invalid: using a reserved keyword as a frame name
<iframe src="https://example.com" name="_blank"></iframe>
Using _blank as an <iframe> name is also invalid because it’s a reserved browsing context keyword. A link targeting _blank would open in a new window/tab rather than inside this <iframe>, which is almost certainly not what you intended.
✅ Fixed: descriptive name without underscore prefix
<iframe src="https://example.com" name="content-frame"></iframe>
<a href="https://example.com/page" target="content-frame">Open in frame</a>
How to fix
- Find every <iframe> element whose name attribute starts with _.
- Rename each one by removing the leading underscore or replacing it with a letter or other valid character.
- Update any target attributes on <a>, <form>, or <base> elements that reference the old name so they match the new name.
- Re-validate your HTML to confirm the issue is resolved.
The <meta> element provides metadata about the HTML document — information that isn’t displayed on the page but is used by browsers, search engines, and other web services. According to the HTML specification, a <meta> tag without any of the recognized attributes is meaningless. The validator flags this because a bare <meta> element (or one with only unrecognized attributes) provides no useful metadata and likely indicates an error or incomplete tag.
This issue commonly occurs when a <meta> tag is left empty by accident, when an attribute name is misspelled (e.g., naem instead of name), or when a required attribute is accidentally deleted during editing.
Most <meta> use cases fall into a few patterns, each requiring specific attribute combinations:
- charset — Used alone to declare the document’s character encoding.
- name + content — Used together to define named metadata like descriptions, viewport settings, or author information.
- http-equiv + content — Used together to simulate an HTTP response header.
- property + content — Used together for Open Graph and similar RDFa-based metadata.
- itemprop + content — Used together for microdata annotations.
Note that content alone is not sufficient — it must be paired with name, http-equiv, property, or itemprop to have meaning.
Examples
Incorrect: bare <meta> tag with no attributes
This triggers the validation error because the <meta> element has no recognized attributes:
<meta>
Incorrect: misspelled attribute
A typo in the attribute name means the validator doesn’t recognize it:
<meta nane="description" content="An example page.">
Incorrect: content without a pairing attribute
The content attribute alone is not enough — it needs name, http-equiv, property, or itemprop:
<meta content="some value">
Correct: character encoding with charset
<meta charset="UTF-8">
Correct: named metadata with name and content
<meta name="description" content="A brief description of the webpage.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Jane Doe">
Correct: HTTP-equivalent with http-equiv and content
<meta http-equiv="X-UA-Compatible" content="IE=edge">
Correct: Open Graph metadata with property and content
<meta property="og:title" content="My Page Title">
<meta property="og:description" content="A summary of the page content.">
Correct: microdata with itemprop and content
<meta itemprop="name" content="Product Name">
Full document example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A brief description of the webpage.">
<meta property="og:title" content="My Page Title">
<title>Example Page</title>
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
How to fix
- Find the flagged <meta> tag in your HTML source at the line number the validator reports.
- Check for typos in attribute names — make sure name, charset, http-equiv, property, or itemprop is spelled correctly.
- Add the missing attribute. Determine what the <meta> tag is supposed to do and add the appropriate attribute(s). If you can’t determine its purpose, it may be safe to remove it entirely.
- Ensure proper pairing. If you’re using content, make sure it’s paired with name, http-equiv, property, or itemprop. The charset attribute is the only one that works on its own without content.
Before HTML5, the way to create a link target within a page was to use a “named anchor” — an <a> element with a name attribute. This allowed other links to jump to that specific spot using a fragment identifier (e.g., href="#section-5"). In HTML5, the name attribute on <a> elements has been marked as obsolete. Instead, the id attribute on any element serves this purpose, making the extra <a> wrapper unnecessary.
This matters for several reasons:
- Standards compliance: Using obsolete attributes means your markup doesn’t conform to the current HTML specification, which can cause W3C validation errors.
- Cleaner markup: Named anchors add an extra element that serves no semantic purpose. Using id directly on the target element is simpler and more meaningful.
- Accessibility: Screen readers and assistive technologies work better with semantic HTML. An id on a heading or <section> provides clearer document structure than a nested anchor element.
- Browser behavior: While browsers still support name for backward compatibility, relying on obsolete features is risky as future browser versions may change or drop support.
To fix this, remove the <a name="..."> element and place an id attribute directly on the nearest appropriate container element, such as a heading (<h2>, <h3>, etc.), a <section>, or a <div>.
Examples
Incorrect: using the obsolete name attribute
<h2>
<a name="section-5">Section 5</a>
</h2>
The <a> element here exists solely to create a link target, adding unnecessary markup.
Correct: using id on the heading
<h2 id="section-5">Section 5</h2>
The id attribute on the <h2> makes it a valid fragment link target without any extra elements.
Linking to the section
Both approaches allow navigation via the same fragment URL. The link syntax doesn’t change:
<a href="#section-5">Jump to Section 5</a>
Using id on other container elements
The id attribute works on any HTML element, so you can place it wherever makes the most sense semantically:
<section id="contact-info">
<h2>Contact Information</h2>
<p>Email us at hello@example.com.</p>
</section>
Incorrect: multiple named anchors in a document
<p>
<a name="intro">Welcome to our page.</a>
</p>
<p>
<a name="conclusion">Thanks for reading.</a>
</p>
Correct: replacing all named anchors with id attributes
<p id="intro">Welcome to our page.</p>
<p id="conclusion">Thanks for reading.</p>
Remember that id values must be unique within a document — no two elements can share the same id. If you’re migrating from name attributes, check for duplicates and ensure each id is used only once.
The name attribute on <a> elements is obsolete in HTML5 and should be replaced with the id attribute.
In older versions of HTML, the name attribute on anchor elements was used to create fragment identifiers — targets you could link to with #section-name in a URL. In HTML5, this approach has been deprecated in favor of the id attribute, which can be placed on any element, not just <a> tags.
Using id is more flexible because you can turn any element into a link target directly, without wrapping it in an anchor. The id attribute works the same way for fragment navigation: a link pointing to #section-name will scroll to the element with id="section-name".
HTML Examples
❌ Obsolete usage with name
<a name="about"></a>
<h2>About Us</h2>
<p>Welcome to our site.</p>
<a href="#about">Go to About</a>
✅ Fixed using id
<h2 id="about">About Us</h2>
<p>Welcome to our site.</p>
<a href="#about">Go to About</a>
The id attribute is placed directly on the <h2> heading, eliminating the need for an empty <a> tag entirely. The #about link works exactly the same way.
The name attribute was historically used on img elements to reference images through JavaScript’s document.images collection or via document.getElementsByName(). In early HTML, name served as an identifier for various elements before the id attribute was widely adopted. The HTML living standard (WHATWG) now marks name as obsolete on img elements, meaning it should no longer be used in new content.
This matters for several reasons:
- Standards compliance: Using obsolete attributes means your HTML does not conform to the current specification, which can cause validation errors and may lead to unexpected behavior in future browser versions.
- Consistency: The id attribute is the universal mechanism for uniquely identifying any HTML element. Using id instead of name keeps your markup consistent and predictable.
- JavaScript and CSS targeting: Modern APIs like document.getElementById() and document.querySelector() work with id, not name on image elements. CSS selectors also target elements by id (e.g., #myImage), making id the more versatile choice.
- Fragment linking: The id attribute allows you to link directly to an element using a URL fragment (e.g., page.html#myImage), whereas the obsolete name attribute on img does not serve this purpose.
To fix this issue, simply replace name with id on your img elements. Keep in mind that id values must be unique within the entire document — no two elements can share the same id. If you have JavaScript code that references the image by name (e.g., document.images["myImage"] or document.getElementsByName("myImage")), update those references to use document.getElementById("myImage") or document.querySelector("#myImage") instead.
Examples
Incorrect: using the obsolete name attribute
<img src="photo.jpg" name="heroImage" alt="A sunset over the ocean">
This triggers the validation error because name is no longer a valid attribute on img.
Correct: using the id attribute
<img src="photo.jpg" id="heroImage" alt="A sunset over the ocean">
The name attribute is replaced with id, and the element can now be targeted with document.getElementById("heroImage") or the CSS selector #heroImage.
Updating JavaScript references
If your existing code references the image by name, update it accordingly.
Before (relying on name):
<img src="logo.png" name="siteLogo" alt="Company logo">
<script>
var logo = document.images["siteLogo"];
logo.style.border = "2px solid blue";
</script>
After (using id):
<img src="logo.png" id="siteLogo" alt="Company logo">
<script>
var logo = document.getElementById("siteLogo");
logo.style.border = "2px solid blue";
</script>
Multiple images that previously shared a name
Since id values must be unique, you cannot give the same id to multiple elements. If you previously used the same name on several images and selected them as a group, switch to a shared class instead:
<img src="slide1.jpg" class="gallery-image" alt="Mountain landscape">
<img src="slide2.jpg" class="gallery-image" alt="Forest trail">
<img src="slide3.jpg" class="gallery-image" alt="River valley">
<script>
var images = document.querySelectorAll(".gallery-image");
images.forEach(function(img) {
img.style.borderRadius = "8px";
});
</script>
This approach is standards-compliant and gives you flexible, modern element selection using class for groups and id for unique elements.
The name attribute was historically used on <option> elements in older HTML specifications, but it has been obsolete since HTML5. The WHATWG HTML Living Standard does not list name as a valid attribute for <option>. The valid attributes for <option> are disabled, label, selected, and value, in addition to the global attributes (such as id, class, style, etc.).
It’s important to understand that the name attribute on <option> never served the same purpose as name on <input> or <select>. For form submission, the browser sends the name from the parent <select> element paired with the value of the selected <option>. Putting name on individual <option> elements has no effect on form data and can mislead developers into thinking it influences form behavior.
Removing the obsolete name attribute ensures your HTML is standards-compliant, avoids confusion for developers maintaining the code, and prevents potential issues with future browser behavior. If you need to reference a specific <option> in JavaScript or CSS, use the id global attribute instead.
Examples
Incorrect: using the obsolete name attribute
<select id="pet-select" name="pet">
<option value="">--Please choose an option--</option>
<option name="dog-option" value="dog">Dog</option>
<option name="cat-option" value="cat">Cat</option>
<option name="hamster-option" value="hamster">Hamster</option>
</select>
This triggers the validation error because name is not a valid attribute on <option>.
Correct: using id instead of name
If you need to uniquely identify each option (for example, to target them with JavaScript or CSS), use the id attribute:
<select id="pet-select" name="pet">
<option value="">--Please choose an option--</option>
<option id="dog-option" value="dog">Dog</option>
<option id="cat-option" value="cat">Cat</option>
<option id="hamster-option" value="hamster">Hamster</option>
</select>
Correct: simply removing name if no reference is needed
In most cases, you don’t need to identify individual options at all. The value attribute is sufficient for form submission, and you can remove name entirely:
<select id="pet-select" name="pet">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="hamster">Hamster</option>
</select>
Note that the name attribute on the <select> element itself is perfectly valid and necessary — it defines the key used when the form data is submitted. The obsolete attribute warning applies only to name on <option> elements.
Ready to validate your sites?
Start your free trial today.