HTML Guides for attribute
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.
When the HTML parser encounters a < character inside an opening tag, it doesn't treat it as the start of a new tag — instead, it tries to interpret it as an attribute name. Since < is not a valid attribute name, the W3C validator raises this error. The browser may still render the page, but the behavior is undefined and can vary across different browsers, potentially leading to broken markup or elements that don't display correctly.
This issue most commonly occurs in a few scenarios:
- Accidental keystrokes — a stray
<typed while editing attributes. - Copy-paste artifacts — fragments of other tags getting pasted into the middle of an element.
- Misplaced angle brackets — attempting to nest or close tags incorrectly, such as adding
<before/>in a self-closing tag. - Template or code generation errors — dynamic HTML output that incorrectly injects
<into attribute positions.
Because this is a syntax-level problem, it can cause cascading parse errors. The parser may misinterpret everything after the stray < until it finds a matching >, which can swallow subsequent elements or attributes and produce unexpected rendering results.
How to Fix It
- Open the file referenced by the validator error and go to the indicated line number.
- Look inside the opening tag of the flagged element for a
<character that doesn't belong. - Remove the stray
<character. - If the
<was meant to represent a literal less-than sign in an attribute value, replace it with the HTML entity<.
Examples
Stray < before the closing slash
<!-- ❌ Stray "<" before the self-closing slash -->
<imgsrc="photo.jpg"alt="smiling cat"</>
<!-- ✅ Fixed: removed the stray "<" -->
<imgsrc="photo.jpg"alt="smiling cat"/>
Stray < between attributes
<!-- ❌ Accidental "<" between attributes -->
<ahref="/about"<class="nav-link">About</a>
<!-- ✅ Fixed: removed the stray "<" -->
<ahref="/about"class="nav-link">About</a>
Fragment of another tag pasted inside an element
<!-- ❌ Leftover "<span" pasted inside the div's opening tag -->
<divclass="card"<span>
<p>Hello world</p>
</div>
<!-- ✅ Fixed: removed the pasted fragment -->
<divclass="card">
<p>Hello world</p>
</div>
Literal < intended in an attribute value
If you actually need a less-than sign inside an attribute value — for example, in a title or data-* attribute — use the < entity instead of a raw <.
<!-- ❌ Raw "<" in an attribute value can cause parsing issues -->
<spantitle="x < 10">Threshold</span>
<!-- ✅ Fixed: use the HTML entity -->
<spantitle="x < 10">Threshold</span>
When graphic design tools like Affinity Designer (formerly Serif) export SVG files, they often embed custom namespace declarations such as xmlns:serif="http://www.serif.com/". These namespaces allow the editor to store its own metadata — like layer names, grouping information, or application-specific settings — inside the SVG file. While this metadata is useful if you re-open the file in the original editor, it has no meaning in a web browser.
The HTML5 specification defines a specific set of namespace attributes that are allowed in SVG elements (such as xmlns, xmlns:xlink, and xmlns:xml). Any namespace prefix not in this predefined list — like xmlns:serif, xmlns:inkscape, or xmlns:sodipodi — triggers this validation error because the HTML parser cannot serialize these attributes back into well-formed XML 1.0. This isn't just a theoretical concern: non-serializable attributes can cause issues when the DOM is manipulated via JavaScript or when the markup is processed by XML-based tools.
Beyond the xmlns:serif declaration itself, you'll likely find attributes in the SVG that use this namespace prefix, such as serif:id="layer1". These should also be removed since they reference a namespace the browser doesn't understand.
How to Fix It
- Remove the
xmlns:serifattribute from the<svg>element. - Remove any attributes prefixed with
serif:(e.g.,serif:id) from child elements within the SVG. - If you re-export the SVG, check your editor's export settings — some tools offer a "clean" or "optimized" export option that strips proprietary metadata.
- Consider using an SVG optimization tool like SVGO to automatically clean up unnecessary attributes.
Examples
❌ Invalid: SVG with xmlns:serif attribute
<svgxmlns="http://www.w3.org/2000/svg"
xmlns:serif="http://www.serif.com/"
viewBox="0 0 100 100"
width="100"
height="100">
<gserif:id="Layer 1">
<circlecx="50"cy="50"r="40"fill="blue"/>
</g>
</svg>
This triggers the error because xmlns:serif is not a recognized namespace in HTML5, and serif:id references that unsupported namespace.
✅ Valid: SVG with proprietary attributes removed
<svgxmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="100"
height="100">
<g>
<circlecx="50"cy="50"r="40"fill="blue"/>
</g>
</svg>
Both xmlns:serif and serif:id have been removed. The SVG renders identically in the browser since those attributes were only meaningful to the editing application.
Handling Multiple Proprietary Namespaces
Exported SVGs sometimes contain several non-standard namespaces at once. Remove all of them:
<!-- ❌ Invalid: multiple proprietary namespaces -->
<svgxmlns="http://www.w3.org/2000/svg"
xmlns:serif="http://www.serif.com/"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 200 200">
<rectx="10"y="10"width="180"height="180"fill="red"
serif:id="background"
inkscape:label="bg-rect"/>
</svg>
<!-- ✅ Valid: all proprietary namespaces and prefixed attributes removed -->
<svgxmlns="http://www.w3.org/2000/svg"
viewBox="0 0 200 200">
<rectx="10"y="10"width="180"height="180"fill="red"/>
</svg>
If you frequently work with SVGs from design tools, integrating an SVG optimizer into your build process can save time and ensure these non-standard attributes never reach production.
When the W3C HTML Validator reports that an attribute is "not serializable as XML 1.0," it means the attribute name contains characters that fall outside the allowed range defined by the XML 1.0 specification. HTML5 documents can be serialized as either HTML or XML (XHTML), and the validator checks that your markup is compatible with both serialization formats. Attribute names in XML 1.0 must start with a letter or underscore and can only contain letters, digits, hyphens, underscores, periods, and certain Unicode characters — they cannot include characters like {, }, @, $, or other symbols commonly found in templating languages.
This issue most frequently appears when a server-side or client-side templating engine (such as Mustache, Handlebars, Angular, Jinja2, or Blade) fails to fully process its expressions before the HTML reaches the browser. Instead of the template placeholder being replaced with a proper value, the raw template syntax ends up in the HTML as a malformed attribute. For example, {{class}} might appear as an attribute name rather than being resolved to its intended value.
Why this matters
- Standards compliance: HTML that isn't serializable as XML 1.0 cannot be reliably converted to XHTML, which limits interoperability.
- Browser inconsistency: Browsers may handle invalid attribute names unpredictably, potentially ignoring the attribute entirely or misinterpreting surrounding markup.
- Accessibility: Malformed attributes can break ARIA attributes or other accessibility-related markup, making content inaccessible to assistive technologies.
- Tooling and parsing: XML-based tools, RSS feeds, and content syndication systems that consume your HTML will choke on attributes that violate XML naming rules.
How to fix it
- Check for unresolved template expressions. Inspect the rendered HTML (not your source templates) for leftover placeholders like
{{...}},<%= ... %>,@{...}, or similar patterns. - Ensure proper server-side rendering. Make sure your templating engine is correctly processing all expressions before the HTML is sent to the client.
- Remove invalid characters from attribute names. If you're using custom attributes, stick to valid
data-*attributes with names consisting only of lowercase letters, digits, and hyphens (after thedata-prefix). - Check for typos. A missing
=sign, quote, or space can cause a value to be interpreted as an attribute name.
Examples
Unresolved template placeholder in an attribute
This occurs when a template expression isn't processed and appears literally in the output:
<!-- ❌ Bad: template syntax rendered as attribute name -->
<div{{classBinding}}id="main">
<p>Hello, world!</p>
</div>
The fix is to ensure the template engine resolves the expression. The rendered output should look like this:
<!-- ✅ Good: attribute properly resolved -->
<divclass="container"id="main">
<p>Hello, world!</p>
</div>
Typo causing a value to be parsed as an attribute name
A missing equals sign or quotation mark can cause part of a value to become an attribute name with invalid characters:
<!-- ❌ Bad: missing = sign causes "bold}" to be treated as an attribute -->
<pstyle"font-weight:bold}" class="intro">Welcome</p>
<!-- ✅ Good: proper attribute syntax -->
<pstyle="font-weight:bold"class="intro">Welcome</p>
Special characters in custom attribute names
Using invalid characters directly in attribute names will trigger this error:
<!-- ❌ Bad: @ and $ are not valid in attribute names -->
<input@change="update"$value="test">
If you need custom attributes, use the standard data-* pattern:
<!-- ✅ Good: valid data attributes -->
<inputdata-change="update"data-value="test">
Angular-style bindings in static HTML
Frameworks like Angular use special attribute syntax (e.g., [property] or (event)) that is only valid within the framework's context and will fail validation if rendered directly:
<!-- ❌ Bad: framework-specific syntax in raw HTML -->
<img[src]="imageUrl"(load)="onLoad()">
If you're generating static HTML, use standard attributes instead:
<!-- ✅ Good: standard HTML attribute -->
<imgsrc="photo.jpg"alt="A photo">
Every HTML element has a defined set of attributes it accepts. The HTML specification maintains strict rules about which attributes belong on which elements. For example, the href attribute is valid on an <a> element but not on a <div>. The for attribute belongs on <label> and <output> elements but not on <span>. When you place an attribute on an element that doesn't recognize it, the validator flags the error.
This issue matters for several reasons. First, browsers may silently ignore unrecognized attributes, meaning your code might appear to work but isn't actually doing anything — leading to hard-to-diagnose bugs. Second, assistive technologies like screen readers rely on valid HTML to correctly interpret page structure and behavior. Invalid attributes can confuse these tools and degrade accessibility. Third, standards-compliant HTML ensures consistent behavior across all browsers and future-proofs your code.
There are several common causes of this error:
- Typos or misspellings — Writing
hieghtinstead ofheight, orscrinstead ofsrc. - Attributes on the wrong element — Using
placeholderon a<div>instead of an<input>or<textarea>. - Obsolete attributes — Using presentational attributes like
align,bgcolor, orborderthat have been removed from the HTML specification in favor of CSS. - Framework-specific attributes — Using attributes like
ng-click(Angular),v-if(Vue), or@click(Vue shorthand) that aren't part of standard HTML. These frameworks typically process them before the browser sees them, but the raw HTML won't validate. - Custom attributes without the
data-*prefix — Inventing your own attributes liketooltiporstatuswithout following thedata-*convention. - ARIA attributes with typos — Writing
aria-roleinstead of the correctrole, oraria-labelledinstead ofaria-labelledby.
Examples
Attribute used on the wrong element
The placeholder attribute is only valid on <input> and <textarea> elements:
<!-- ❌ "placeholder" not allowed on "div" -->
<divplaceholder="Enter text here">Content</div>
<!-- ✅ Use placeholder on a supported element -->
<inputtype="text"placeholder="Enter text here">
Obsolete presentational attribute
The align attribute has been removed from most elements in HTML5. Use CSS instead:
<!-- ❌ "align" not allowed on "div" -->
<divalign="center">Centered content</div>
<!-- ✅ Use CSS for presentation -->
<divstyle="text-align: center;">Centered content</div>
Custom attribute without data-* prefix
If you need to store custom data on an element, use the data-* attribute format:
<!-- ❌ "tooltip" not allowed on "span" -->
<spantooltip="More information">Hover me</span>
<!-- ✅ Use a data-* attribute for custom data -->
<spandata-tooltip="More information">Hover me</span>
The data-* attributes are specifically designed for embedding custom data. You can access them in JavaScript via the dataset property, e.g., element.dataset.tooltip.
Misspelled attribute
A simple typo can trigger this error:
<!-- ❌ "widht" not allowed on "img" -->
<imgsrc="photo.jpg"widht="300"alt="A photo">
<!-- ✅ Correct the spelling -->
<imgsrc="photo.jpg"width="300"alt="A photo">
ARIA attribute typo
ARIA attributes must match their exact specification names:
<!-- ❌ "aria-labelled" not allowed on "input" -->
<inputtype="text"aria-labelled="name-label">
<!-- ✅ Use the correct ARIA attribute name -->
<inputtype="text"aria-labelledby="name-label">
Framework-specific attributes
If you're using a JavaScript framework and want your source templates to validate, be aware that framework-specific syntax won't pass validation. In Vue, for example, you can use the data-* equivalent or accept that templates are preprocessed:
<!-- ❌ "v-if" not allowed on "div" -->
<divv-if="isVisible">Hello</div>
<!-- This is expected with Vue templates and is typically not a concern, since the framework processes these before they reach the browser. -->
since the framework processes these before they reach the browser. -->
When encountering this error, check the MDN Web Docs reference for the element in question to see which attributes it actually supports. This will quickly clarify whether you need to fix a typo, move the attribute to a different element, replace it with CSS, or convert it to a data-* attribute.
The xmlns:dt attribute — short for "XML Namespace: datatypes" — was historically used in Microsoft-specific XML vocabularies (notably urn:schemas-microsoft-com:datatypes) to declare data type information on elements. It was common in older ASP and IE-era markup. However, HTML5 is not an XML language, and it does not support arbitrary XML namespace declarations on elements.
In HTML5, the only xmlns attribute permitted is xmlns="http://www.w3.org/1999/xhtml" on the <html> element itself, and even that exists solely for compatibility with XHTML serialization. Namespace-prefixed attributes like xmlns:dt, xmlns:o, or xmlns:v are invalid. The HTML parser simply does not recognize them, and the W3C validator will flag them with the error "Attribute 'xmlns:dt' not allowed here."
Why This Is a Problem
- Standards compliance: Using non-standard attributes means your document does not conform to the HTML specification, which can lead to unpredictable behavior across browsers.
- Legacy lock-in: The
xmlns:dtattribute is tied to Microsoft's proprietary data type schema. Modern browsers do not interpret or use this namespace, so it serves no functional purpose in an HTML5 document. - Validation noise: Invalid attributes generate validator errors that can obscure real issues in your markup, making it harder to catch genuine bugs.
- Accessibility and tooling: Screen readers, search engine crawlers, and other automated tools expect valid HTML. Non-standard attributes can confuse parsers or be silently discarded.
How to Fix It
- Remove the attribute. If
xmlns:dtwas carried over from legacy code or a CMS template and nothing in your application depends on it, simply delete it. - Replace with
data-*attributes. If you need to attach custom metadata to an element — for example, to indicate a data type for use by JavaScript — use an HTML5data-*attribute instead. - Use XHTML if XML namespaces are required. If you genuinely need XML namespace support (rare in modern web development), serve your document as
application/xhtml+xmlwith a proper XHTML doctype and XML declaration. Be aware this changes parsing rules significantly.
Examples
Incorrect: Using xmlns:dt in HTML5
This will trigger the validation error:
<ulxmlns:dt="urn:schemas-microsoft-com:datatypes">
<lidt:dt="string">Item one</li>
<lidt:dt="number">42</li>
</ul>
Both xmlns:dt on the <ul> and the dt:dt attributes on the <li> elements are invalid in HTML5.
Correct: Attribute removed
If the namespace declaration is unnecessary (which it almost always is in modern HTML), remove it along with any prefixed attributes:
<ul>
<li>Item one</li>
<li>42</li>
</ul>
Correct: Using data-* attributes for custom metadata
If your JavaScript or application logic needs to know the data type of each item, use valid data-* attributes:
<ul>
<lidata-type="string">Item one</li>
<lidata-type="number">42</li>
</ul>
You can then access these values in JavaScript with element.dataset.type.
Correct: Migrating a legacy div wrapper
A common legacy pattern places xmlns:dt on a container div:
<!-- Invalid -->
<divxmlns:dt="urn:schemas-microsoft-com:datatypes">
<spandt:dt="dateTime">2024-01-15</span>
</div>
The fixed version removes the namespace and uses standard attributes:
<div>
<timedatetime="2024-01-15">January 15, 2024</time>
</div>
In this case, the semantic <time> element with its datetime attribute is the proper HTML5 way to represent date and time values — no custom namespace needed.
Quick Checklist
- Search your codebase for
xmlns:dtand anydt:prefixed attributes. - Check CMS templates, server-generated markup, and copy-pasted legacy code — these are the most common sources.
- Remove the attributes or replace them with
data-*equivalents. - Re-validate your document to confirm the error is resolved.
A < character appearing where an attribute name is expected typically means a closing > is missing on the previous tag, causing the browser to interpret the next tag as an attribute.
This error occurs when you forget to close an HTML element's opening tag with >. The validator sees the < of the next element and thinks it's still parsing attributes of the previous element. It's a common typo that can cascade into multiple confusing errors.
For example, if you write <div without the closing >, the following <p> tag gets parsed as if it were an attribute of the div, triggering this error.
HTML Examples
❌ Incorrect
<divclass="container"
<p>Hello, world!</p>
</div>
The <div> tag is missing its closing > after "container", so the validator sees <p> as part of the div's attribute list.
✅ Correct
<divclass="container">
<p>Hello, world!</p>
</div>
Make sure every opening tag is properly closed with >. If the error points to a specific line, check the tag immediately before that line for a missing >.
When the HTML parser encounters a tag's attributes, it expects a specific structure: an attribute name, followed by an equals sign, followed by a quoted value. If a quote character appears where the parser expects an attribute name, it means something has gone wrong in the syntax earlier in the tag. The validator flags this as Quote """ in attribute name and suggests that a matching quote is likely missing somewhere before.
This issue matters because browsers will try to recover from the malformed HTML in unpredictable ways. One browser might ignore the attribute entirely, while another might merge it with adjacent text. This can lead to broken styling, missing functionality, or elements that behave differently across browsers. For accessibility, malformed attributes can prevent assistive technologies from correctly interpreting element semantics and roles.
There are several common causes for this error:
- Missing equals sign between an attribute name and its value, causing the parser to treat the opening quote as part of the attribute name.
- Extra closing quote that prematurely ends an attribute value, leaving subsequent quotes orphaned.
- Unescaped quotes inside attribute values, which break the quoting structure of the entire tag.
- Copy-paste errors that introduce curly/smart quotes (
"") or extra quote characters. - A missing closing quote on a previous attribute, causing the parser to consume subsequent attributes as part of that value.
Examples
Missing equals sign
The most common cause. Without the =, the parser sees class as one attribute and then encounters " where it expects another attribute name.
❌ Incorrect:
<pclass"news">This paragraph has broken markup.</p>
✅ Fixed:
<pclass="news">This paragraph has correct markup.</p>
Missing closing quote on a previous attribute
When a quote is left unclosed, everything after it—including other attributes—gets consumed as part of the value, until the parser eventually encounters another quote in an unexpected position.
❌ Incorrect:
<ahref="/about class="link">About us</a>
Here, the href value is never closed. The parser reads /about class= as the href value, then encounters "link" in an unexpected context.
✅ Fixed:
<ahref="/about"class="link">About us</a>
Extra quote character
A stray extra quote breaks the pairing of subsequent quotes.
❌ Incorrect:
<divid=""main" class="container">Content</div>
✅ Fixed:
<divid="main"class="container">Content</div>
Unescaped quotes inside an attribute value
If the attribute value itself contains a double quote, it must be escaped as " or the attribute must use single quotes instead.
❌ Incorrect:
<inputtype="text"value="She said "hello"">
✅ Fixed (using "):
<inputtype="text"value="She said "hello"">
✅ Also fixed (using single quotes for the attribute):
<inputtype="text"value='She said "hello"'>
Smart/curly quotes from copy-paste
Word processors and rich-text editors often convert straight quotes to curly quotes, which are not valid for HTML attribute delimiters.
❌ Incorrect:
<pclass="highlight">Styled text</p>
✅ Fixed:
<pclass="highlight">Styled text</p>
How to debug this issue
When you see this error, the validator usually points to a specific line number, but the root cause may be on that line or earlier in the same tag. Follow these steps:
- Go to the line indicated by the validator and examine the full tag.
- Check every attribute on that element for proper
name="value"syntax. - Count the quotes — each attribute value should have exactly one opening and one closing quote.
- Look for missing
=signs between attribute names and their values. - Search for curly quotes (
",",',') and replace them with straight quotes ("or'). - If the line looks correct, check the preceding lines — an unclosed quote on a previous element can cascade errors into later markup.
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