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>
<htmllang="en">
<head>
<title>My Page</title>
<imgsrc="photo.jpg"alt="A smiling cat">
<metaname="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>
<htmllang="en">
<head>
<title>My Page</title>
<metaname="description"content="A page about cats">
</head>
<body>
<imgsrc="photo.jpg"alt="A smiling cat">
<p>Welcome!</p>
</body>
</html>
A <meta> tag accidentally placed in <body>
<!DOCTYPE html>
<htmllang="en">
<head>
<title>My Page</title>
</head>
<body>
<metaname="author"content="Jane Doe">
<p>Hello world</p>
</body>
</html>
Move the <meta> tag into <head>:
<!DOCTYPE html>
<htmllang="en">
<head>
<title>My Page</title>
<metaname="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>
<htmllang="en">
<head>
<title>My Page</title>
<linkrel="stylesheet"href="style.css"
<metaname="viewport"content="width=device-width, initial-scale=1">
</head>
<body>
<p>Content</p>
</body>
</html>
Close the <link> tag properly:
<!DOCTYPE html>
<htmllang="en">
<head>
<title>My Page</title>
<linkrel="stylesheet"href="style.css">
<metaname="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
nameoridcannot 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
namewithidand provide a meaningful, non-empty value if you need a fragment target. - Move the
idto a nearby semantic element instead of using a standalone empty<a>tag. For example, place theiddirectly on a heading, section, or paragraph. - Ensure uniqueness — every
idvalue in a document must be unique.
Examples
❌ Empty name attribute triggers the error
<aname=""></a>
<h2>Introduction</h2>
<p>Welcome to the guide.</p>
❌ Empty name generated by a template
<aname=""></a>
<p>This anchor was meant to be a target but the value is missing.</p>
<ahref="#">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
<h2id="introduction">Introduction</h2>
<p>Welcome to the guide.</p>
<!-- Link to the section from elsewhere -->
<ahref="#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:
<aid="section-start"></a>
<p>This paragraph follows the anchor point.</p>
<ahref="#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) -->
<aname="contact"></a>
<!-- After (modern HTML) -->
<aid="contact"></a>
<!-- Even better: put the id on a semantic element -->
<h2id="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
nameattribute is unnecessary. You can useidinstead 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
<formname="">
<labelfor="email">Email</label>
<inputtype="email"id="email"name="email">
<buttontype="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>
<labelfor="email">Email</label>
<inputtype="email"id="email"name="email">
<buttontype="submit">Subscribe</button>
</form>
If you don't need to reference the form by name, simply remove the attribute.
✅ Fixed: meaningful name provided
<formname="subscriptionForm">
<labelfor="email">Email</label>
<inputtype="email"id="email"name="email">
<buttontype="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
<formid="subscription-form">
<labelfor="email">Email</label>
<inputtype="email"id="email"name="email">
<buttontype="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
nameattribute is present, its value must not be empty. - JavaScript references: An empty
namemakes it difficult to reference the element using methods likedocument.getElementsByName()orFormData. - Accessibility: Screen readers and assistive technologies may use the
nameattribute 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
<formaction="/submit"method="post">
<labelfor="email">Email:</label>
<inputtype="email"id="email"name="">
<buttontype="submit">Submit</button>
</form>
✅ Providing a meaningful name value
<formaction="/submit"method="post">
<labelfor="email">Email:</label>
<inputtype="email"id="email"name="email">
<buttontype="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:
<labelfor="search">Filter results:</label>
<inputtype="text"id="search">
❌ Multiple inputs with empty names
This pattern sometimes appears when inputs are generated dynamically with placeholder attributes:
<formaction="/register"method="post">
<inputtype="text"name="">
<inputtype="password"name="">
<buttontype="submit">Register</button>
</form>
✅ Each input gets a descriptive name
<formaction="/register"method="post">
<labelfor="username">Username:</label>
<inputtype="text"id="username"name="username">
<labelfor="password">Password:</label>
<inputtype="password"id="password"name="password">
<buttontype="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
<iframesrc="https://example.com"name="_example"></iframe>
<ahref="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
<iframesrc="https://example.com"name="example"></iframe>
<ahref="https://example.com/page"target="example">Open in frame</a>
✅ Fixed: underscore used elsewhere in the name
<iframesrc="https://example.com"name="my_example"></iframe>
<ahref="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
<iframesrc="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
<iframesrc="https://example.com"name="content-frame"></iframe>
<ahref="https://example.com/page"target="content-frame">Open in frame</a>
How to fix
- Find every
<iframe>element whosenameattribute starts with_. - Rename each one by removing the leading underscore or replacing it with a letter or other valid character.
- Update any
targetattributes 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:
<metanane="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:
<metacontent="some value">
Correct: character encoding with charset
<metacharset="UTF-8">
Correct: named metadata with name and content
<metaname="description"content="A brief description of the webpage.">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<metaname="author"content="Jane Doe">
Correct: HTTP-equivalent with http-equiv and content
<metahttp-equiv="X-UA-Compatible"content="IE=edge">
Correct: Open Graph metadata with property and content
<metaproperty="og:title"content="My Page Title">
<metaproperty="og:description"content="A summary of the page content.">
Correct: microdata with itemprop and content
<metaitemprop="name"content="Product Name">
Full document example
<!DOCTYPE html>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<metaname="description"content="A brief description of the webpage.">
<metaproperty="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, oritempropis 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 withname,http-equiv,property, oritemprop. Thecharsetattribute is the only one that works on its own withoutcontent.
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
iddirectly on the target element is simpler and more meaningful. - Accessibility: Screen readers and assistive technologies work better with semantic HTML. An
idon a heading or<section>provides clearer document structure than a nested anchor element. - Browser behavior: While browsers still support
namefor 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>
<aname="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
<h2id="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:
<ahref="#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:
<sectionid="contact-info">
<h2>Contact Information</h2>
<p>Email us at hello@example.com.</p>
</section>
Incorrect: multiple named anchors in a document
<p>
<aname="intro">Welcome to our page.</a>
</p>
<p>
<aname="conclusion">Thanks for reading.</a>
</p>
Correct: replacing all named anchors with id attributes
<pid="intro">Welcome to our page.</p>
<pid="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
<aname="about"></a>
<h2>About Us</h2>
<p>Welcome to our site.</p>
<ahref="#about">Go to About</a>
✅ Fixed using id
<h2id="about">About Us</h2>
<p>Welcome to our site.</p>
<ahref="#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
idattribute is the universal mechanism for uniquely identifying any HTML element. Usingidinstead ofnamekeeps your markup consistent and predictable. - JavaScript and CSS targeting: Modern APIs like
document.getElementById()anddocument.querySelector()work withid, notnameon image elements. CSS selectors also target elements byid(e.g.,#myImage), makingidthe more versatile choice. - Fragment linking: The
idattribute allows you to link directly to an element using a URL fragment (e.g.,page.html#myImage), whereas the obsoletenameattribute onimgdoes 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
<imgsrc="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
<imgsrc="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):
<imgsrc="logo.png"name="siteLogo"alt="Company logo">
<script>
varlogo=document.images["siteLogo"];
logo.style.border="2px solid blue";
</script>
After (using id):
<imgsrc="logo.png"id="siteLogo"alt="Company logo">
<script>
varlogo=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:
<imgsrc="slide1.jpg"class="gallery-image"alt="Mountain landscape">
<imgsrc="slide2.jpg"class="gallery-image"alt="Forest trail">
<imgsrc="slide3.jpg"class="gallery-image"alt="River valley">
<script>
varimages=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
<selectid="pet-select"name="pet">
<optionvalue="">--Please choose an option--</option>
<optionname="dog-option"value="dog">Dog</option>
<optionname="cat-option"value="cat">Cat</option>
<optionname="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:
<selectid="pet-select"name="pet">
<optionvalue="">--Please choose an option--</option>
<optionid="dog-option"value="dog">Dog</option>
<optionid="cat-option"value="cat">Cat</option>
<optionid="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:
<selectid="pet-select"name="pet">
<optionvalue="">--Please choose an option--</option>
<optionvalue="dog">Dog</option>
<optionvalue="cat">Cat</option>
<optionvalue="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.
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
Pro Trial
Full Pro access. Cancel anytime.
Start Pro Trial →Join teams across 40+ countries