HTML Guides for quote
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.
The decoding attribute of an <img> is set to something other than sync, async or auto.
decoding is a hint about when the browser should decode the image. async says the image can be decoded without delaying the rest of the content, sync asks for it to be decoded and shown together with the content around it, and auto, the default, leaves the choice to the browser. The value has to be one of those three lowercase keywords with nothing around it. A typo such as asynch, a keyword that belongs to another attribute such as lazy (that one goes in loading), uppercase ASYNC and an empty value all trigger this error.
When the reported value includes quotes, as in "async", the quotes are inside the value itself. That usually happens when the quotes around the value were HTML-encoded as ", often by a plugin or template that escaped markup a second time. " can't delimit an attribute, so the parser reads decoding="async" as an unquoted value and decodes both references into literal quotes. Wrapping the value in two sets of quotes, as in decoding='"async"', gives the same result. A value with only a trailing quote, such as async", means the opening quote is missing, and the validator also reports “"” in an unquoted attribute value.
Browsers treat an invalid value as auto, so the image still loads and displays, but the hint is lost. If you don't need a particular decoding mode, remove the attribute.
The " cause rarely affects decoding alone. If loading, width, height, srcset or sizes on the same <img> also report a stray ", fix the code that writes the tag instead of editing each attribute.
Invalid example
<img src="photo.jpg" alt="A red bicycle" width="600" height="400" decoding="async">
<img src="photo.jpg" alt="A red bicycle" width="600" height="400" decoding="asynch">
Valid example
<img src="photo.jpg" alt="A red bicycle" width="600" height="400" decoding="async">
The fetchpriority attribute of an <img> is set to something other than high, low or auto.
fetchpriority is a hint about how soon the browser should fetch the image compared with the other images on the page. high suits the main image at the top of the page, low suits images that start out of view, such as the later slides of a carousel, and auto, the default, leaves the choice to the browser. The value has to be one of those three keywords with nothing around it. A made-up level such as highest, a keyword that belongs to another attribute such as eager (that one goes in loading) and an empty value all trigger this error.
When the reported value includes quotes, as in "high", the quotes are inside the value itself. That usually happens when the quotes around the value were HTML-encoded as ", often by a plugin or template that escaped markup a second time. " can't delimit an attribute, so the parser reads fetchpriority="high" as an unquoted value and decodes both references into literal quotes. Wrapping the value in two sets of quotes, as in fetchpriority='"high"', gives the same result. A value with only a trailing quote, such as high", means the opening quote is missing, and the validator also reports “"” in an unquoted attribute value.
Browsers treat an invalid value as auto, so the image still loads, but at the default priority. A hero image meant to be high can then start downloading later than intended. If you don't need a particular priority, remove the attribute.
The " cause rarely affects fetchpriority alone. If decoding, width, height, srcset or sizes on the same <img> also report a stray ", fix the code that writes the tag instead of editing each attribute.
Invalid example
<img src="hero.jpg" alt="A mountain lake at sunrise" width="1200" height="600" fetchpriority="high">
<img src="hero.jpg" alt="A mountain lake at sunrise" width="1200" height="600" fetchpriority="highest">
Valid example
<img src="hero.jpg" alt="A mountain lake at sunrise" width="1200" height="600" fetchpriority="high">
The height attribute of an <img> has a literal " character inside its value, which may only contain digits.
height takes a non-negative integer such as 109, with no quotes, units or spaces. The quotes around an attribute value are HTML syntax, not part of the value. When an extra " ends up inside it, the validator stops at that character and rejects the value.
A value that starts with the quote, such as "109", usually comes from one of two mistakes. In the first, the quotes around the value were HTML-encoded as ", often by a plugin or template that escaped markup a second time. " can't delimit an attribute, so the parser reads height="109" as an unquoted value and decodes both references into literal quotes. In the second, the value is wrapped in two sets of quotes, as in height='"109"'.
A value that ends with the quote, such as 109", means the opening quote is missing (height=109") or the quotes don't match (height='109"'). Without an opening quote, the validator also reports “"” in an unquoted attribute value.
Browsers read 109" as 109, so that case often looks fine. A value that starts with the quote fails to parse, and the browser ignores height. Without it, the browser can't work out the image's aspect ratio before the file loads, so it reserves no vertical space and the content below shifts once the image arrives.
The cause rarely affects height alone. If width, srcset or sizes on the same <img> also report a stray ", fix the code that writes the tag instead of editing each attribute.
Invalid example
<img src="logo.png" alt="Company logo" width="600" height="109">
<img src="logo.png" alt="Company logo" width="600" height=109">
Valid example
<img src="logo.png" alt="Company logo" width="600" height="109">
The href value of a mailto: link contains a double quote ("), which the URL can only hold percent-encoded as %22.
The ilto: in the message is the tail of mailto:, and the check covers the whole address after it, so a " at the end of the address gets the same error as one at the start.
Usually the quotes were meant for the attribute and landed after the scheme, as in <a href=mailto:"info@example.com">. No quote follows the =, so HTML reads mailto:"info@example.com" as an unquoted value and copies both " characters into the URL. On that tag the validator also reports “"” in an unquoted attribute value. If a space follows the stray quote, the value ends at the space and the message shows only mailto:". Without a closing quote, a single " stays in front of the address.
Quoting the address on purpose doesn't help. In href='mailto:"info@example.com"' and href="mailto:"info@example.com"", the URL still starts with a literal " when the validator checks it. A display name in email header style, such as mailto:"Jane Doe" <info@example.com>, fails for the same reason: the URL holds only the address, and the name goes in the link text. For the rare address with a quoted local part, RFC 6068 asks for the quotes as %22, as in mailto:%22info%22@example.com.
Invalid example
<a href=mailto:"info@example.com">Email us</a>
Valid example
<a href="mailto:info@example.com">info@example.com</a>
This tel: link has a double quote (") inside its href value, and " is not allowed in a URL.
The usual cause is quotes around the phone number instead of around the attribute value. In <a href=tel:"555-0100">, the value itself is unquoted, so the HTML parser keeps both quote marks as part of it and the URL becomes tel:"555-0100". For the same tag, the validator also reports “"” in an unquoted attribute value. Writing href='tel:"555-0100"', or using " entities, gives the same result, because " turns into a real " before the URL is checked.
For the number itself, RFC 3966 allows digits, a leading +, and the visual separators -, ., ( and ). Quote the whole attribute value and keep the number bare inside it. The link text can show the number in whatever format reads best. A value that holds two numbers has to become two links. Tel: with a capital T is fine, since scheme names are case-insensitive, though most pages write tel:.
Invalid example
<a href=tel:"+1-555-0100">Call us</a>
Valid example
<a href="tel:+1-555-0100">+1 555-0100</a>
The href value on the <a> element contains a literal " character, which is not allowed in a URL path.
The quotes around an attribute value are HTML syntax, not part of the URL. A " inside the value is different: written as ", or typed inside a single-quoted attribute such as href='"/brochure.pdf"', it becomes a character of the URL itself. The URL standard does not allow a raw " in a path, so the validator rejects the whole value. Browsers still follow the link, but they send the quote as %22 and request a path that usually does not exist.
The stray quote rarely comes from someone typing it. More often the code that writes the link adds it. A template that JSON-encodes the URL before printing it, for example with JSON.stringify(url), wraps the address in an extra pair of quotes. A CMS that stores link settings as JSON, like {"url":"/brochure.pdf","target":"_blank"}, can print the wrong piece of that string, so href ends up holding a fragment such as "url":"/brochure.pdf" or the tail of the object instead of the address. Fix the template so it outputs the plain URL. If a file name really contains a double quote, write it as %22 in the path.
Invalid example
<a href=""/brochure.pdf"">Download the brochure</a>
Valid example
<a href="/brochure.pdf">Download the brochure</a>
The value of the sizes attribute on an <img> starts with a literal " character, which can't begin a media condition or a CSS length.
sizes holds a comma-separated list of source sizes. Each one is an optional media condition followed by a length, as in (max-width: 600px) 100vw, and the last one is usually a plain length such as 600px. Lazy-loaded images can also start the list with auto. The quotes around an attribute value are HTML syntax, not part of the value. When an extra " ends up inside it, the validator tries to read the entry as a length, finds the quote where it expects a digit or a minus sign, and rejects the value.
The stray quote usually comes from one of two mistakes. In the first, the quotes around the value were HTML-encoded as ", often by a plugin or template that escaped markup a second time. " can't delimit an attribute, so the parser reads sizes="(max-width: as an unquoted value that stops at the first space. The rest of the list turns into stray attributes such as 600px) and 100vw,, which the validator reports separately, and the bad value in this message is only the first word, such as "(max-width: or "auto,. In the second, the value is wrapped in two sets of quotes, as in sizes='"100vw"', and the whole list is the bad value.
Browsers drop a sizes value they can't parse and fall back to 100vw. They then pick the srcset candidate meant for a full-width layout, which is often a larger file than the image slot needs.
The cause rarely affects sizes alone. If width, height or srcset on the same <img> also report a stray ", fix the code that writes the tag instead of editing each attribute.
Invalid example
<img
src="logo-600.png"
alt="Company logo"
srcset="logo-600.png 600w, logo-1200.png 1200w"
sizes="(max-width: 600px) 100vw, 600px">
Valid example
<img
src="logo-600.png"
alt="Company logo"
srcset="logo-600.png 600w, logo-1200.png 1200w"
sizes="(max-width: 600px) 100vw, 600px">
The first image URL in the srcset attribute starts with a literal " character, which is not allowed in a URL path.
srcset holds a comma-separated list of image candidates. Each one is a URL, optionally followed by a width descriptor such as 600w or a pixel density descriptor such as 2x. The quotes around an attribute value are HTML syntax, not part of the value. When an extra " ends up inside the value, it becomes the first character of the first URL. A raw " is not allowed in a URL path segment, so the validator rejects that candidate. Browsers read "https://example.com/logo.png as a relative path, because a URL scheme has to start with a letter, and request a file on your own site that does not exist.
The stray quote usually comes from one of two mistakes. In the first, the quotes around the value were HTML-encoded as ", often by a plugin or template that escaped markup a second time. " can't delimit an attribute, so the parser reads srcset="logo-600.png as an unquoted value that stops at the first space. The rest of the list turns into stray attributes such as 600w,, which the validator reports separately, and the bad value in this message is only the first URL. In the second, the value is wrapped in two sets of quotes, as in srcset='"logo-600.png 600w"', and the whole list is the bad value.
The cause rarely affects srcset alone. If width, height, sizes or decoding on the same <img> also report a stray ", fix the code that writes the tag instead of editing each attribute.
Invalid example
<img
src="logo-600.png"
alt="Company logo"
srcset="logo-600.png 600w, logo-1200.png 1200w"
sizes="(max-width: 600px) 100vw, 600px">
Valid example
<img
src="logo-600.png"
alt="Company logo"
srcset="logo-600.png 600w, logo-1200.png 1200w"
sizes="(max-width: 600px) 100vw, 600px">
A stray double quote ended up inside the width value of an <img>, usually because the opening quote is missing (width=200") or the quotes don't match (width='200"').
The width attribute takes a non-negative integer: digits only, with no quotes, units or spaces. Without an opening quote, the browser reads the value as unquoted, which runs until the next space or >, so the closing " becomes part of the value. The validator reports this case twice, once with this message and once as “"” in an unquoted attribute value. When the value opens with a single quote and closes with a double quote, it runs until the next single quote, and the " again lands inside it.
Browsers parse width leniently and read 200" as 200, so the image often looks fine. A value that starts with the quote, such as "200", fails to parse, and the browser ignores it. The image then gets no reserved space before it loads, and the content below it shifts once it arrives.
Templates and string-built HTML cause most of these, for example width=<%= width %>" with the opening quote left out. Put matching double quotes around the number.
Invalid example
<img src="photo.jpg" alt="A red car" width=200" height="150">
<img src="photo.jpg" alt="A red car" width='200"' height="150">
Valid example
<img src="photo.jpg" alt="A red car" width="200" height="150">
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.
A <meta> tag has stray quote characters right after its name, as in <meta"" name="description">, so the parser reads them as part of the element name.
In a start tag, the element name runs until the first space, / or >. With no space between meta and the quotes, the browser creates an unknown element called meta"" instead of a <meta> element. The name attribute isn't allowed on that unknown element, which is what this warning reports. Single quotes (<meta'') or a different number of quotes give the same message.
The warning is the mildest part of the problem. Because there is no real <meta> element, the description, viewport or other metadata in the tag never takes effect, and search engines don't see it either. The unknown element also ends the <head> early, and since it has no end tag, it wraps the rest of the page. Expect several errors on the same line in the report, including one that calls meta"" a completely unknown element and a "Stray end tag" error for head.
Remove the quotes so that a space follows meta. If a template or CMS writes the tag, fix it there: the quotes can come from an empty variable or attribute printed right after the tag name. Correcting the tag also clears the other errors it caused.
Invalid example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My page</title>
<meta"" name="description" content="A short summary of the page.">
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
Valid example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My page</title>
<meta name="description" content="A short summary of the page.">
</head>
<body>
<p>Hello, world!</p>
</body>
</html>
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.
1K Weekly
1,000 monthly checks. Cancel anytime.
Get 1K Weekly →Join teams across 40+ countries