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 -->
<img src="photo.jpg" alt="smiling cat" < />
<!-- ✅ Fixed: removed the stray "<" -->
<img src="photo.jpg" alt="smiling cat" />
Stray < between attributes
<!-- ❌ Accidental "<" between attributes -->
<a href="/about" < class="nav-link">About</a>
<!-- ✅ Fixed: removed the stray "<" -->
<a href="/about" class="nav-link">About</a>
Fragment of another tag pasted inside an element
<!-- ❌ Leftover "<span" pasted inside the div's opening tag -->
<div class="card" <span>
<p>Hello world</p>
</div>
<!-- ✅ Fixed: removed the pasted fragment -->
<div class="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 -->
<span title="x < 10">Threshold</span>
<!-- ✅ Fixed: use the HTML entity -->
<span title="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:serif attribute 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
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:serif="http://www.serif.com/"
viewBox="0 0 100 100"
width="100"
height="100">
<g serif:id="Layer 1">
<circle cx="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
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="100"
height="100">
<g>
<circle cx="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 -->
<svg xmlns="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">
<rect x="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 -->
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 200 200">
<rect x="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 the data- 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 -->
<div class="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 -->
<p style"font-weight:bold}" class="intro">Welcome</p>
<!-- ✅ Good: proper attribute syntax -->
<p style="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 -->
<input data-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 -->
<img src="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 hieght instead of height, or scr instead of src.
- Attributes on the wrong element — Using placeholder on a <div> instead of an <input> or <textarea>.
- Obsolete attributes — Using presentational attributes like align, bgcolor, or border that 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 like tooltip or status without following the data-* convention.
- ARIA attributes with typos — Writing aria-role instead of the correct role, or aria-labelled instead of aria-labelledby.
Examples
Attribute used on the wrong element
The placeholder attribute is only valid on <input> and <textarea> elements:
<!-- ❌ "placeholder" not allowed on "div" -->
<div placeholder="Enter text here">Content</div>
<!-- ✅ Use placeholder on a supported element -->
<input type="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" -->
<div align="center">Centered content</div>
<!-- ✅ Use CSS for presentation -->
<div style="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" -->
<span tooltip="More information">Hover me</span>
<!-- ✅ Use a data-* attribute for custom data -->
<span data-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" -->
<img src="photo.jpg" widht="300" alt="A photo">
<!-- ✅ Correct the spelling -->
<img src="photo.jpg" width="300" alt="A photo">
ARIA attribute typo
ARIA attributes must match their exact specification names:
<!-- ❌ "aria-labelled" not allowed on "input" -->
<input type="text" aria-labelled="name-label">
<!-- ✅ Use the correct ARIA attribute name -->
<input type="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" -->
<div v-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. -->
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 is not permitted on standard HTML elements according to the HTML specification.
HTML5 does not use XML namespaces like xmlns:dt, which are only valid in certain XML vocabularies such as XHTML or when embedding MathML or SVG. In typical HTML, attributes with xmlns or any custom XML namespace prefixes are invalid and cause validation errors.
To fix this issue, simply remove the xmlns:dt attribute from your HTML tags.
If you are using a data attribute or a custom attribute, you can use data-* attributes instead, which are allowed in HTML5.
Incorrect usage with xmlns:dt:
<div xmlns:dt="urn:schemas-microsoft-com:datatypes">
Content here
</div>
Correct usage—attribute removed:
<div>
Content here
</div>
If you need to store custom data, use data-* attributes:
<div data-dt="urn:schemas-microsoft-com:datatypes">
Content here
</div>
Avoid using XML namespaces in HTML5 documents to ensure your code is standards-compliant.
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:
<p class"news">This paragraph has broken markup.</p>
✅ Fixed:
<p class="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:
<a href="/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:
<a href="/about" class="link">About us</a>
Extra quote character
A stray extra quote breaks the pairing of subsequent quotes.
❌ Incorrect:
<div id=""main" class="container">Content</div>
✅ Fixed:
<div id="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:
<input type="text" value="She said "hello"">
✅ Fixed (using "):
<input type="text" value="She said "hello"">
✅ Also fixed (using single quotes for the attribute):
<input type="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:
<p class="highlight">Styled text</p>
✅ Fixed:
<p class="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.
Ready to validate your sites?
Start your free trial today.