HTML Guides for svg
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.
Namespaced attributes like xmlns:inkscape are not valid in HTML5 documents and should be removed from inline SVGs.
When you copy an SVG directly from editors like Inkscape or Adobe Illustrator, the markup often includes custom namespace declarations such as xmlns:inkscape or xmlns:sodipodi. These namespaces are used internally by the editor to store metadata like layer names, version info, and other tool-specific data.
In an HTML5 document, the HTML parser only recognizes a limited set of namespaces — specifically xmlns, xmlns:xlink, and the default SVG namespace. Any other namespaced attributes are not serializable as XML 1.0, which triggers this validation error.
The fix is straightforward: remove the editor-specific namespace declarations and any attributes that use those prefixes (e.g., inkscape:version, sodipodi:docname). These attributes serve no purpose in the browser and are safe to delete.
HTML Examples
❌ Invalid: editor-specific namespaces in inline SVG
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.0.dtd"
inkscape:version="1.3"
sodipodi:docname="icon.svg"
width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
✅ Valid: clean inline SVG without editor namespaces
<svg xmlns="http://www.w3.org/2000/svg"
width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Most SVG optimization tools like SVGO or Jake Archibald's SVGOMG will automatically strip these editor-specific namespaces and attributes for you.
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
<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.
The xmlns attribute defines the XML namespace for an element. For SVG, the correct namespace is http://www.w3.org/2000/svg, declared with xmlns="http://www.w3.org/2000/svg". The xmlns:svg attribute attempts to declare an additional prefixed namespace binding — essentially mapping the prefix svg: to the same namespace URI. This is redundant because the default (unprefixed) namespace already covers all SVG elements.
In HTML5, the parser handles namespaces internally. The HTML specification only permits a small set of namespace attributes: xmlns on certain elements (like <svg> and <math>) and xmlns:xlink for legacy compatibility. Arbitrary prefixed namespace declarations like xmlns:svg are not part of the HTML serialization format. The W3C validator raises this error because attributes containing colons in their local names (other than the specifically allowed ones) cannot be round-tripped through the HTML parser and serializer — they are "not serializable as XML 1.0."
Why this matters
- Standards compliance: HTML5 has strict rules about which namespace declarations are permitted. Using
xmlns:svgviolates these rules. - Serialization issues: If a browser parses the HTML and then re-serializes it (e.g., via
innerHTML), thexmlns:svgattribute may be lost, altered, or cause unexpected behavior because it falls outside the serializable attribute set. - Redundancy: Even in pure XML/SVG documents, declaring
xmlns:svg="http://www.w3.org/2000/svg"alongsidexmlns="http://www.w3.org/2000/svg"is unnecessary. The default namespace already applies to the<svg>element and all its unprefixed descendants.
How to fix it
- Locate the
<svg>element (or any element) that contains thexmlns:svgattribute. - Remove
xmlns:svg="http://www.w3.org/2000/svg"entirely. - Ensure the standard
xmlns="http://www.w3.org/2000/svg"attribute remains if needed (note that when embedding SVG inline in an HTML5 document, evenxmlnsis optional since the HTML parser infers the namespace automatically).
Examples
Incorrect: redundant prefixed namespace declaration
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
The xmlns:svg attribute triggers the validation error because it is not serializable in HTML.
Correct: standard namespace only
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Correct: inline SVG in HTML5 without any namespace attribute
When SVG is embedded directly in an HTML5 document, the HTML parser automatically assigns the correct namespace, so you can omit xmlns altogether:
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
This is perfectly valid and is the most common pattern for inline SVG in modern HTML. The xmlns attribute is only strictly necessary when the SVG is served as a standalone XML file (with a .svg extension or an image/svg+xml content type).
The xmlns:cc attribute declares the Creative Commons namespace used in SVG metadata, and HTML doesn't allow prefixed namespace declarations on <svg> or any other element.
Files saved by Inkscape often have xmlns:cc="http://creativecommons.org/ns#" on the root <svg> element. The prefix is for the Creative Commons terms in the file's RDF metadata. <cc:Work> wraps the description of the drawing, and if you pick a license under Document Properties, <cc:license> records it. In a standalone .svg file, which is XML, the declaration is valid. The error shows up when that markup ends up inside an HTML page, pasted by hand or inlined by a template or build step.
The HTML parser doesn't process namespace declarations, so xmlns:cc stays a plain attribute with a colon in its name. The validator rejects it on <svg>, and on <html> or <div> too. On <svg> it accepts just two namespace attributes, xmlns and xmlns:xlink. Inkscape exports usually put xmlns:cc next to xmlns:dc, xmlns:rdf, xmlns:sodipodi and xmlns:inkscape, and each of those gets its own message.
Delete xmlns:cc from the <svg> tag, and delete the <metadata> block with it. The cc: elements in that block break for the same parser reason. <cc:Work> becomes an SVG element whose name happens to contain a colon, and the validator reports cc:work and cc:license as completely-unknown elements in SVG content. None of the metadata is drawn, so the image doesn't change.
That block may be the only place the file states its license. If the license matters, keep the original .svg, metadata and all, in your source files, and show the license where readers can see it, such as in a caption under the image.
To stop the declaration from coming back, optimize the SVG before it gets inlined. SVGO's default preset runs removeEditorsNSData, which removes the Creative Commons namespace along with the Inkscape and Sodipodi ones, and removeMetadata, which removes the <metadata> block.
Invalid example
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
width="120" height="120" viewBox="0 0 24 24">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<cc:license rdf:resource="https://creativecommons.org/licenses/by/4.0/" />
</cc:Work>
</rdf:RDF>
</metadata>
<path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="2" />
</svg>
Valid example
<figure>
<svg width="120" height="120" viewBox="0 0 24 24" role="img">
<title>Checkmark</title>
<path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="2" />
</svg>
<figcaption>
Icon licensed under <a href="https://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
</figcaption>
</figure>
Custom XML namespace declarations like xmlns:dc are not allowed on <svg> elements in HTML5 documents.
In HTML5 (as opposed to XHTML), the parser only recognizes a limited set of namespace attributes on SVG elements: xmlns and xmlns:xlink. Any other namespace declarations, such as xmlns:dc, xmlns:cc, xmlns:rdf, or xmlns:svg, are invalid. These namespaces are commonly added by SVG editors like Inkscape but serve no purpose in an HTML5 context.
The SVG metadata that relies on these namespaces (like Dublin Core dc: elements or Creative Commons cc: elements) is also typically unnecessary when embedding SVGs in HTML. You can safely remove these namespace declarations and their associated metadata elements without affecting how the SVG renders.
Invalid Example
<svg xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="100"
height="100">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:title>My Icon</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Valid Example
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="100"
height="100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Remove all non-standard xmlns: attributes and the <metadata> block they support. If you're exporting from a tool like Inkscape, look for a "plain SVG" or "optimized SVG" export option, or use a tool like SVGO to clean up the output automatically.
The xmlns:inkscape attribute declares the namespace Inkscape uses for its own editor data, and HTML doesn't allow prefixed namespace declarations on <svg> or any other element.
Inkscape's default file format, Inkscape SVG, puts xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" on the root <svg> element. The prefix marks attributes that only Inkscape reads: inkscape:version records the release that saved the file, and inkscape:groupmode="layer" with an inkscape:label turns a <g> into a named layer. Inkscape 0.92 also writes inkscape:connector-curvature="0" on paths, and inkscape:export-filename remembers where the last PNG export went. Browsers ignore all of them, so the image looks the same without them.
In an HTML page the declaration does nothing. The HTML parser doesn't handle namespace prefixes, so xmlns:inkscape is a plain attribute with a colon in its name, and the validator reports it on any element that carries it. Each inkscape: attribute gets its own message as well, such as Attribute "inkscape:version" not allowed on element "svg" at this point. Inkscape SVG files usually declare xmlns:sodipodi next to it, for attributes like sodipodi:docname, and the validator reports that declaration separately.
Delete xmlns:inkscape and every attribute that starts with inkscape:. Removing only the declaration leaves the attribute errors behind. The layers turn into plain groups and lose their labels, so if a stylesheet or script needs to find one, use the group's id (Inkscape assigns ids like layer1) or add a class.
When you clean up a standalone .svg file, remove the declaration and the attributes together. Delete xmlns:inkscape but leave a single inkscape:label behind, and the file stops being well-formed XML, because it uses a prefix it never declares. Browsers then refuse to display it (Firefox reports an "unbound prefix").
To get a copy without the Inkscape markup, use File > Save a Copy and choose Optimized SVG or Plain SVG. Optimized SVG runs Scour, which strips editor data unless you check its "Keep editor data" option. Plain SVG drops the inkscape: and sodipodi: markup but still writes xmlns:svg, which the validator also rejects.
Keep the Inkscape SVG as the file you edit. A copy without the editor data reopens without its layers, and shapes drawn with the star tool come back as plain paths. If a build step inlines your SVGs, SVGO removes the same markup with removeEditorsNSData, which is part of its default preset.
Invalid example
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:version="1.3.2"
width="24" height="24" viewBox="0 0 24 24">
<g inkscape:label="Icon" inkscape:groupmode="layer" id="layer1">
<path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="2" />
</g>
</svg>
Valid example
<svg xmlns="http://www.w3.org/2000/svg"
width="24" height="24" viewBox="0 0 24 24">
<g id="layer1">
<path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="2" />
</g>
</svg>
In XML and XHTML, the xmlns attribute is used to declare namespaces that allow elements and attributes from different vocabularies to coexist without naming conflicts. The xmlns:o prefix specifically declares the Microsoft Office namespace (urn:schemas-microsoft-com:office:office), which enables Office-specific elements and attributes like <o:p> (Office paragraph markers) within the document.
HTML5, however, is not an XML language. The HTML5 specification only permits the xmlns attribute on the <html> element (and only with the value http://www.w3.org/1999/xhtml), along with xmlns:xlink on SVG elements. Custom namespace prefixes like xmlns:o, xmlns:v (VML), and xmlns:w (Word) are not recognized as valid attributes on any HTML5 element and will trigger validation errors.
Why This Happens
This issue most commonly occurs when:
- Content is pasted from Microsoft Word into a WYSIWYG editor or CMS. Word generates its own flavor of HTML that includes Office namespace declarations and proprietary elements.
- HTML files are exported from Office applications like Word, Excel, or Outlook. These exports produce markup heavily reliant on Office-specific namespaces.
- Email templates are built using tools that generate Office-compatible HTML, carrying namespace baggage into standard web pages.
Why It Matters
- Standards compliance: HTML5 does not support arbitrary XML namespace declarations, so these attributes make your document invalid.
- Bloated markup: Office-generated HTML often includes not just the namespace declarations but also large amounts of Office-specific elements, conditional comments, and inline styles that increase page size significantly.
- Maintenance difficulty: Office-flavored HTML is harder to read, edit, and maintain compared to clean, standards-compliant markup.
- Potential rendering issues: While browsers generally ignore unrecognized attributes, the accompanying Office-specific elements (like
<o:p>) can occasionally cause unexpected spacing or layout behavior.
How to Fix It
- Remove all
xmlns:oattributes from your HTML elements. - Remove any Office-specific elements such as
<o:p>,<o:SmartTagType>, or similar tags that rely on the Office namespace. - Check for other Office namespaces like
xmlns:v,xmlns:w,xmlns:m, andxmlns:st1— these should also be removed. - Clean pasted content before inserting it into your HTML. Many text editors and CMS platforms offer a "Paste as plain text" option that strips out Office formatting.
- If you use a CMS or rich text editor, look for a "Clean up Word HTML" or similar feature to automatically strip Office artifacts.
Examples
❌ Invalid: Office namespace declarations on elements
<!DOCTYPE html>
<html lang="en">
<head>
<title>Company Report</title>
</head>
<body xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w="urn:schemas-microsoft-com:office:word">
<h1>Quarterly Report</h1>
<p class="MsoNormal">Revenue increased by 15% this quarter.<o:p></o:p></p>
<p class="MsoNormal">Expenses remained stable.<o:p></o:p></p>
</body>
</html>
This markup contains three Office namespace declarations on the <body> element and uses <o:p> elements inside paragraphs — all of which are invalid in HTML5.
✅ Valid: Clean HTML without Office namespaces
<!DOCTYPE html>
<html lang="en">
<head>
<title>Company Report</title>
</head>
<body>
<h1>Quarterly Report</h1>
<p>Revenue increased by 15% this quarter.</p>
<p>Expenses remained stable.</p>
</body>
</html>
❌ Invalid: Namespace on a div element
<div xmlns:o="urn:schemas-microsoft-com:office:office">
<p class="MsoNormal">Meeting notes from Tuesday.<o:p></o:p></p>
</div>
✅ Valid: Clean version
<div>
<p>Meeting notes from Tuesday.</p>
</div>
Notice that in the corrected examples, the class="MsoNormal" attribute was also removed. While MsoNormal is technically a valid class name that won't cause a validation error, it's an Office-generated class with no purpose unless you have corresponding CSS rules — removing it keeps your markup clean.
If you genuinely need XML namespace support for document processing, use a proper XHTML document served with the application/xhtml+xml content type, or handle the XML processing separately from your web-facing HTML.
The xmlns:rdf attribute declares the RDF namespace that SVG editors use for the metadata block in a drawing, and HTML doesn't allow prefixed namespace declarations on <svg> or any other element.
Inkscape SVG files, such as those saved by Inkscape 0.92, declare xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" on the root <svg> element, next to xmlns:dc and xmlns:cc. RDF (Resource Description Framework) is the W3C model for describing things as statements, and the rdf: namespace holds its core terms. Inkscape uses them to build the <metadata> block. <rdf:RDF> wraps the description, rdf:about="" says it is about this file, and rdf:resource gives a property a URI as its value, such as the Dublin Core type StillImage. The title and format are Dublin Core (dc:) terms, and the license is a Creative Commons (cc:) one. In a standalone .svg file, which is XML, all of this is valid.
Inline the file in an HTML page and the block stops being RDF. The HTML parser doesn't process namespace declarations, so xmlns:rdf is a plain attribute with a colon in its name, and the validator reports it on <svg>, on <html> and on any other element. The elements lose their namespace too. <rdf:RDF> becomes an SVG element named rdf:rdf, which the validator reports as a completely-unknown element, along with every element nested in it.
Delete xmlns:rdf together with the <metadata> block. Removing only the declaration leaves all those unknown-element errors in place. Nothing in the block is drawn, so the image doesn't change. The same export usually declares xmlns:dc, xmlns:cc, xmlns:sodipodi and xmlns:inkscape too. Each gets its own message, and they all go in the same cleanup.
If the page needs machine-readable facts about the image, such as who made it or what license it has, describe it in JSON-LD instead. A <script type="application/ld+json"> block with a schema.org ImageObject can hold creator and license, and its contentUrl points at the image file, for example the original .svg with its metadata intact. Google's image metadata documentation asks for contentUrl plus at least one of creator, creditText, copyrightNotice or license.
On <html>, xmlns:rdf is a leftover from XHTML+RDFa 1.0, which declared prefixes with xmlns:. RDFa 1.1 uses the prefix attribute instead, and rdf is one of its predefined prefixes, so you can delete the declaration without adding anything in its place.
To keep the declaration out of inlined SVGs, run them through SVGO first. Its default preset includes removeEditorsNSData, whose list of editor namespaces contains RDF, and removeMetadata, which drops the <metadata> block.
Invalid example
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
width="240" height="160" viewBox="0 0 240 160">
<metadata>
<rdf:RDF>
<rdf:Description rdf:about="">
<dc:title>Route map</dc:title>
<dc:creator>Jane Doe</dc:creator>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</rdf:Description>
</rdf:RDF>
</metadata>
<path d="M20 140L120 20L220 140" fill="none" stroke="currentColor" stroke-width="4" />
</svg>
Valid example
<svg width="240" height="160" viewBox="0 0 240 160" role="img">
<title>Route map</title>
<path d="M20 140L120 20L220 140" fill="none" stroke="currentColor" stroke-width="4" />
</svg>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ImageObject",
"contentUrl": "https://example.com/images/route-map.svg",
"name": "Route map",
"creator": { "@type": "Person", "name": "Jane Doe" },
"license": "https://creativecommons.org/licenses/by/4.0/"
}
</script>
In HTML5, the only namespace attributes recognized on SVG elements are xmlns (for the SVG namespace) and xmlns:xlink (for XLink, though xlink is now largely deprecated in favor of plain attributes). Any other custom namespace declarations — such as xmlns:serif, xmlns:inkscape, or xmlns:sketch — are not permitted by the HTML specification and will trigger a validation error.
Design tools like Affinity Designer, Adobe Illustrator, Inkscape, and Sketch often embed proprietary namespace declarations and metadata attributes in exported SVG files. These serve as internal markers for the design application (for example, to preserve layer names or editor-specific settings) but have no meaning in a web browser. Browsers simply ignore them, so they add unnecessary bytes to your page without providing any benefit.
Removing these attributes is important for several reasons:
- Standards compliance: The HTML5 parser has a fixed list of allowed namespace declarations. Custom ones violate the spec.
- Clean markup: Proprietary metadata bloats your SVG files with information that only matters inside the originating design tool.
- Maintainability: Removing tool-specific artifacts makes your SVGs easier to read, edit, and optimize.
To fix this, open your SVG file (or the HTML file containing inline SVGs) and remove the xmlns:serif attribute from the <svg> element. You should also search for and remove any attributes prefixed with serif: (such as serif:id) throughout the SVG, since those depend on the now-removed namespace declaration.
For a more automated approach, consider using SVGO or similar SVG optimization tools, which strip out editor metadata and unnecessary namespace declarations by default.
Examples
Incorrect — custom namespace attribute present
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:serif="https://www.serif.com/"
viewBox="0 0 100 100">
<circle serif:id="MainCircle" cx="50" cy="50" r="40" fill="blue" />
</svg>
This triggers two types of errors: xmlns:serif is not allowed on the <svg> element, and serif:id is not a recognized attribute on <circle>.
Correct — custom namespace and prefixed attributes removed
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Incorrect — multiple proprietary namespaces
Design tools sometimes add several custom namespaces at once:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:serif="https://www.serif.com/"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 200 200">
<g serif:id="Layer1">
<rect x="10" y="10" width="80" height="80" fill="red" />
</g>
</svg>
Correct — only standard namespaces retained
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 200 200">
<g>
<rect x="10" y="10" width="80" height="80" fill="red" />
</g>
</svg>
Note that xmlns:xlink was also removed in this example. While it won't always trigger a validation error by itself, it's unnecessary if no xlink:href attributes are used — and modern HTML5 SVG usage favors plain href over xlink:href anyway.
The xmlns:sketch attribute declares the namespace the Sketch design app used for its layer data, and HTML doesn't allow prefixed namespace declarations on <svg> or any other element.
Sketch is a macOS design app from Bohemian Coding. Until version 3.6, it put xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" on the root <svg> of every SVG it exported. The prefix is there for the sketch:type attributes, which record what each element was in the Sketch document: MSPage on the page group, MSArtboardGroup on the artboard, MSLayerGroup on a group of layers and MSShapeGroup on each shape. Sketch 3.6, released in March 2016, dropped these prefixes to make its SVG exports smaller. An SVG that still carries them was exported before then and ended up in a page or template later.
The HTML parser doesn't handle namespace prefixes, so xmlns:sketch is a plain attribute with a colon in its name. The validator reports it on any element that carries it, whether that's <svg> or a <div>. Each sketch:type gets its own message too, such as Attribute "sketch:type" not allowed on element "path" at this point. Browsers ignore this markup, so removing it doesn't change how the icon looks.
Delete xmlns:sketch and every sketch:type attribute. Removing only the declaration leaves one error per sketch:type behind. Delete them together in a standalone .svg file too: if a sketch:type survives without its declaration, the file is no longer well-formed XML and browsers won't display it.
Sketch's export also copies the layer name into <title> and adds <desc>Created with Sketch.</desc>. Neither one is a validation error. In inline SVG, though, the browser uses <title> as the image's accessible name and <desc> as its description, so a screen reader can announce "Created with Sketch." Give the <title> a name that describes the icon, and delete the <desc>.
If a build step inlines your SVG files, SVGO removes the Sketch markup for you. Its default preset runs removeEditorsNSData, and http://www.bohemiancoding.com/sketch/ns is on that plugin's list of editor namespaces, so it deletes the declaration and every sketch: attribute. The preset's removeDesc plugin deletes a <desc> that starts with "Created with".
Invalid example
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>check</title>
<desc>Created with Sketch.</desc>
<g id="Page-1" stroke="none" fill="none" sketch:type="MSPage">
<g id="Icons" sketch:type="MSArtboardGroup">
<path d="M5 12l5 5L20 7" id="check" stroke="#000000" stroke-width="2" sketch:type="MSShapeGroup"></path>
</g>
</g>
</svg>
Valid example
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Checkmark</title>
<g id="Page-1" stroke="none" fill="none">
<g id="Icons">
<path d="M5 12l5 5L20 7" id="check" stroke="#000000" stroke-width="2"></path>
</g>
</g>
</svg>
The xmlns:sodipodi attribute declares the namespace for editor data that Inkscape inherited from Sodipodi, and HTML doesn't allow prefixed namespace declarations on <svg> or any other element.
Sodipodi was a vector drawing program written mainly by Lauris Kaplinski, and SVG was its native file format. In 2003 a group of its developers forked it to start Inkscape. Sodipodi itself stopped at version 0.34, released in February 2004. Inkscape kept the sodipodi: prefix for the features it inherited, so files saved by current versions still declare xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" on the root <svg>. The URI is only a name for the namespace. Nothing downloads that DTD.
The prefix marks editor state. <sodipodi:namedview>, a child of the root <svg>, keeps the document's view settings: page and border colors, the grid, zoom and window position, the current layer, and any guide lines as <sodipodi:guide> children. On the root element, sodipodi:docname records the file name the drawing was last saved under.
Shapes and text carry their own sodipodi: attributes. sodipodi:nodetypes on a path has one letter per node (c for cusp, s for smooth, z for symmetric, a for auto-smooth), which the node tool reads to decide how a node's handles move. sodipodi:type marks a path drawn with a shape tool, such as star, arc or spiral, and attributes like sodipodi:sides and sodipodi:r1 keep the shape's parameters so Inkscape can bring its handles back. Lines of text get sodipodi:role="line" on their <tspan>. Browsers ignore all of it, and a star is drawn from the path's d attribute like any other path.
The HTML parser doesn't link prefixes to declarations. To it, xmlns:sodipodi is one attribute with a colon in its name and sodipodi:docname is another, and nothing connects the two. Delete only the declaration and every other sodipodi: name still fails on its own. The invalid example below gets 13 errors, and only one of them is about xmlns:sodipodi. The other 12 come from the sodipodi: attributes, such as Attribute "sodipodi:type" not allowed on element "path" at this point., and from <sodipodi:namedview> and <sodipodi:guide>, which the validator reports as completely-unknown elements in SVG content.
Delete xmlns:sodipodi, the <sodipodi:namedview> element with everything inside it, and every attribute that starts with sodipodi:. The image looks the same afterwards. Only Inkscape notices: the guides, grid and page settings are gone, and stars and spirals reopen as plain paths. Keep the original file for editing and put a cleaned copy in the page.
The same Inkscape file usually declares xmlns:inkscape, xmlns:rdf, xmlns:cc and xmlns:dc too, and each gets its own message. SVGO's removeEditorsNSData plugin, part of its default preset, removes the Sodipodi declaration and every sodipodi: element and attribute, and does the same for those four namespaces. If the whole file was pasted in, its <?xml version="1.0"?> line comes along too, and the validator reports it as an XML processing instruction.
Invalid example
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
sodipodi:docname="star.svg"
width="24" height="24" viewBox="0 0 24 24">
<sodipodi:namedview pagecolor="#ffffff" showgrid="false">
<sodipodi:guide position="12,12" orientation="1,0" />
</sodipodi:namedview>
<path sodipodi:type="star" sodipodi:sides="5"
sodipodi:cx="12" sodipodi:cy="12" sodipodi:r1="10" sodipodi:r2="4"
sodipodi:arg1="-1.5708" sodipodi:arg2="-0.9425"
d="M12,2 14.35,8.76 21.51,8.91 15.8,13.24 17.88,20.09 12,16 6.12,20.09 8.2,13.24 2.49,8.91 9.65,8.76Z"
fill="currentColor" />
</svg>
Valid example
<svg xmlns="http://www.w3.org/2000/svg"
width="24" height="24" viewBox="0 0 24 24">
<path d="M12,2 14.35,8.76 21.51,8.91 15.8,13.24 17.88,20.09 12,16 6.12,20.09 8.2,13.24 2.49,8.91 9.65,8.76Z"
fill="currentColor" />
</svg>
In HTML5, SVG elements are natively supported and don't require explicit namespace declarations at all. When you write an <svg> tag inside an HTML document, the browser automatically associates it with the correct SVG namespace (http://www.w3.org/2000/svg). The xmlns:svg="http://www.w3.org/2000/svg" attribute is a prefixed namespace binding — it declares svg as a namespace prefix — which is a concept from XML/XHTML workflows that HTML5's parser does not support or recognize.
The HTML specification defines a limited set of allowed attributes on each element. Since xmlns:svg is not among them for the <svg> element (or any HTML5 element), the W3C validator flags it as invalid. The only namespace-related attribute the HTML parser tolerates on <svg> is xmlns="http://www.w3.org/2000/svg", and even that is optional — it's accepted purely for compatibility with XHTML but has no functional effect in HTML5.
This issue commonly appears when SVG code is exported from graphic editors like Inkscape or Adobe Illustrator, or when SVG files originally written as standalone XML documents are pasted directly into HTML. These tools sometimes include verbose namespace declarations that are necessary in XML contexts but invalid in HTML.
Why it matters
- Standards compliance: The HTML5 specification explicitly does not allow prefixed namespace attributes. Using them results in validation errors.
- Code cleanliness: Unnecessary attributes add clutter without any benefit, making your markup harder to read and maintain.
- Potential parsing issues: While most browsers silently ignore unrecognized attributes, relying on lenient browser behavior rather than valid markup can lead to unexpected results in edge cases or non-browser HTML consumers (e.g., email clients, content scrapers, or accessibility tools).
How to fix it
- Locate all
<svg>elements in your HTML that contain thexmlns:svgattribute. - Remove the
xmlns:svg="http://www.w3.org/2000/svg"attribute entirely. - If you're working in an HTML5 document (not XHTML), the
xmlns="http://www.w3.org/2000/svg"attribute is also optional — you can keep or remove it. - If your SVG uses other prefixed namespace declarations like
xmlns:xlink, consider replacing them with their HTML5 equivalents (e.g., usehrefinstead ofxlink:href).
Examples
Incorrect: using xmlns:svg on an SVG element
The xmlns:svg attribute triggers the validation error:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Correct: removing the prefixed namespace
Remove xmlns:svg and keep only the standard attributes:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Also correct: minimal inline SVG in HTML5
In HTML5, the xmlns attribute itself is optional for inline SVG, so this is the cleanest approach:
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Cleaning up multiple unnecessary namespaces
SVG exported from editors often includes several unnecessary namespace declarations. Here's a before-and-after of a typical cleanup:
Before (multiple invalid namespace attributes):
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<image xlink:href="photo.jpg" width="200" height="200" />
</svg>
After (cleaned up for HTML5):
<svg viewBox="0 0 200 200">
<image href="photo.jpg" width="200" height="200" />
</svg>
Note that xlink:href has been replaced with href, which is the modern standard supported by all current browsers. The xmlns:xlink declaration is no longer needed either.
The aria-labelledby attribute is an IDREFS attribute, meaning its value must be a space-separated list of one or more id values that exist in the document. These referenced elements collectively provide the accessible name for the element. When the value is an empty string ("") or contains only whitespace, there are no valid ID references, which violates the IDREFS requirement defined in the WAI-ARIA and HTML specifications.
This issue commonly appears when templating systems or JavaScript frameworks conditionally set aria-labelledby but output an empty string when no label ID is available. It also occurs when developers add the attribute as a placeholder with the intention of filling it in later but forget to do so.
Why this matters
An empty aria-labelledby is problematic for several reasons:
- Accessibility: Screen readers rely on
aria-labelledbyto announce the accessible name of an element. An empty value can cause unpredictable behavior — some screen readers may ignore the SVG entirely, while others may fall back to reading unhelpful content or nothing at all. This leaves users who depend on assistive technology without a meaningful description of the graphic. - Standards compliance: The W3C validator flags this as an error because the HTML specification requires IDREFS attributes to contain at least one non-whitespace character. Shipping invalid HTML can signal broader quality issues and may cause problems in strict parsing environments.
- Maintainability: An empty
aria-labelledbyis ambiguous. It's unclear whether the developer intended the SVG to be decorative, forgot to add a reference, or encountered a bug in their templating logic.
How to fix it
Choose the approach that matches your intent:
- Reference a labeling element by ID: If the SVG conveys meaning, add a
<title>element (or another visible text element) inside or near the SVG with a uniqueid, then setaria-labelledbyto thatid. IDs are case-sensitive, so ensure an exact match. - Use
aria-labelinstead: If you want to provide an accessible name directly as a text string without needing a separate element, replacearia-labelledbywitharia-label. - Remove the attribute: If the SVG already has an accessible name through other means (such as visible adjacent text or a
<title>child that doesn't need explicit referencing), simply remove the emptyaria-labelledby. - Mark as decorative: If the SVG is purely decorative and adds no information, remove
aria-labelledbyand addaria-hidden="true"so assistive technology skips it entirely.
When generating aria-labelledby dynamically, ensure your code omits the attribute entirely rather than outputting an empty value when no label ID is available.
Examples
❌ Empty aria-labelledby (triggers the error)
<svg role="img" aria-labelledby="">
<use href="#icon-star"></use>
</svg>
The empty string is not a valid IDREFS value, so the validator reports an error.
✅ Reference a <title> element by ID
<svg role="img" aria-labelledby="star-title">
<title id="star-title">Favorite</title>
<use href="#icon-star"></use>
</svg>
The aria-labelledby points to the <title> element's id, giving the SVG a clear accessible name of "Favorite."
✅ Use aria-label with a text string
<svg role="img" aria-label="Favorite">
<use href="#icon-star"></use>
</svg>
When you don't need to reference another element, aria-label provides the accessible name directly as an attribute value.
✅ Reference multiple labeling elements
<svg role="img" aria-labelledby="star-title star-desc">
<title id="star-title">Favorite</title>
<desc id="star-desc">A five-pointed star icon</desc>
<use href="#icon-star"></use>
</svg>
The aria-labelledby value can include multiple space-separated IDs. The accessible name is constructed by concatenating the text content of the referenced elements in order.
✅ Decorative SVG (no accessible name needed)
<svg aria-hidden="true" focusable="false">
<use href="#icon-decorative-divider"></use>
</svg>
For purely decorative graphics, aria-hidden="true" removes the element from the accessibility tree. Adding focusable="false" prevents the SVG from receiving keyboard focus in older versions of Internet Explorer and Edge.
The xmlns attribute declares the XML namespace for an element. For SVG elements, the only permitted namespace is "http://www.w3.org/2000/svg". When this attribute is present but set to an empty string ("") or any value other than the correct namespace, the W3C validator reports an error because the browser cannot properly associate the element with the SVG specification.
In HTML5 documents (served as text/html), the xmlns attribute on <svg> is actually optional. The HTML parser automatically associates <svg> elements with the correct SVG namespace without needing an explicit declaration. However, if you do include the xmlns attribute — for example, because your SVG was exported from a design tool or copied from an XML-based source — it must contain the exact value "http://www.w3.org/2000/svg". An empty or incorrect value will cause a validation error and could lead to rendering issues in certain contexts.
This matters for several reasons:
- Standards compliance: The HTML specification explicitly restricts the allowed value for
xmlnson SVG elements. - Browser compatibility: While most modern browsers are forgiving in HTML mode, an incorrect namespace can cause problems when SVG content is used in XML contexts (such as XHTML or standalone
.svgfiles). - Interoperability: Tools and libraries that process your HTML may rely on the correct namespace to identify and manipulate SVG elements.
To fix this issue, you have two options:
- Set the correct value: Replace the empty or incorrect
xmlnsvalue with"http://www.w3.org/2000/svg". - Remove the attribute entirely: Since
xmlnsis optional in HTML5, simply removing it is often the cleanest solution.
Examples
Incorrect: empty xmlns attribute
This triggers the validation error because the namespace value is an empty string:
<svg xmlns="" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
Incorrect: wrong namespace value
Any value other than the correct SVG namespace will also trigger this error:
<svg xmlns="http://www.w3.org/2000/html" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
Fix: use the correct namespace
Set xmlns to the only permitted value:
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
Fix: remove the xmlns attribute
In an HTML5 document, you can omit xmlns altogether since the parser handles the namespace automatically:
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
Note on inline SVG from external sources
Design tools like Figma, Illustrator, or Inkscape often export SVG files with the xmlns attribute already set correctly. If you're copying SVG markup and the xmlns value gets accidentally cleared or corrupted during the process, either restore it to "http://www.w3.org/2000/svg" or remove it before embedding the SVG in your HTML. Both approaches will produce valid, working markup.
An XML namespace URI is a unique identifier, not an actual web address that your browser fetches. The SVG namespace was defined as http://www.w3.org/2000/svg in the original SVG specification, and that exact string is what HTML parsers and validators expect. Even though using https everywhere is a best practice for real network requests, namespace URIs are not network requests — they are simply fixed strings used to identify which XML vocabulary an element belongs to.
When you write https://www.w3.org/2000/svg instead of http://www.w3.org/2000/svg, the validator sees an unrecognized namespace. This can also cause problems in certain XML-based contexts (such as XHTML or standalone SVG files), where the browser may fail to recognize the element as SVG at all, resulting in your graphics not rendering. In standard HTML5 mode, most browsers will still render inline SVGs correctly regardless of the xmlns value, but the markup is technically invalid and may cause issues in stricter parsing environments like XML serializers, server-side renderers, or tools that process SVG as XML.
This mistake is especially common because many developers reflexively change http to https — or their editor or linter automatically does — when they see a URL-like string. The same principle applies to other namespace URIs like http://www.w3.org/1999/xhtml for HTML and http://www.w3.org/1998/Math/MathML for MathML. These are all fixed identifiers that must not be altered.
How to Fix It
Replace https:// with http:// in the xmlns attribute value. That's it — no other changes are needed.
If your project uses automated tooling that rewrites http URLs to https, you may need to configure an exception for XML namespace URIs.
Examples
❌ Incorrect: Using https in the namespace URI
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
This triggers the validation error because https://www.w3.org/2000/svg is not a recognized namespace value.
✅ Correct: Using http in the namespace URI
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
✅ Correct: Inline SVG in HTML without xmlns
When embedding SVG directly inside an HTML5 document, the xmlns attribute is optional — the HTML parser automatically assigns the correct namespace to <svg> elements:
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
This is perfectly valid HTML5. You only need the xmlns attribute when the SVG is served as a standalone .svg file or used within an XHTML document.
The display attribute on an <svg> element does not accept CSS values like inline-block. The display attribute in SVG is a presentation attribute that only accepts SVG-specific values: inline, block, list-item, none, and a few others defined in the SVG specification, but not inline-block.
SVG presentation attributes map to a limited subset of CSS properties, and their allowed values don't always match the full range of CSS values. The display presentation attribute on SVG elements accepts values like inline, block, none, run-in, table, and related table display values, but inline-block is not among them.
To apply inline-block display behavior to an <svg> element, use a style attribute or a CSS rule instead of the display presentation attribute.
Invalid example
<svg display="inline-block" width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
Valid example
Use the style attribute to set inline-block:
<svg style="display: inline-block" width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
Or apply it through CSS:
<style>
.icon {
display: inline-block;
}
</style>
<svg class="icon" width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>
This W3C validation error has two distinct problems combined into one message. First, the value "none" is not a recognized value for the text-anchor attribute — the only accepted values are start, middle, and end. Second, the <g> element is a generic container used to group SVG shapes together and does not support the text-anchor attribute directly.
The text-anchor attribute controls how text is aligned relative to its anchor point (the x coordinate). A value of start aligns the beginning of the text to the anchor, middle centers the text on the anchor, and end aligns the end of the text to the anchor. There is no "none" value because text always needs an alignment — start is the default if the attribute is omitted.
Why this is a problem
- Invalid markup: Using an unrecognized value like
"none"means browsers must guess the intended behavior, which can lead to inconsistent rendering across different environments. - Wrong element: The
<g>element does not directly render text, sotext-anchorhas no meaningful effect on it. While CSS inheritance might cause child text elements to pick up styles from a parent<g>, thetext-anchorpresentation attribute is only valid on elements that actually render text content. - Standards compliance: The SVG specification explicitly defines which elements accept
text-anchorand which values are allowed. Violating this produces validation errors and may cause issues with SVG processing tools.
How to fix it
- Remove the attribute from the
<g>element and apply it to the appropriate text element inside the group. - Replace
"none"with a valid value:start,middle, orend. If you want the default behavior (left-aligned for LTR text), simply omit the attribute entirely, asstartis the default. - If you need to set
text-anchorfor multiple text elements inside a group, use CSS instead of the presentation attribute.
Examples
❌ Invalid: "none" on a <g> element
<svg width="200" height="200">
<g text-anchor="none">
<text x="100" y="100">Hello</text>
</g>
</svg>
✅ Fixed: valid value on the <text> element
<svg width="200" height="200">
<text x="100" y="100" text-anchor="middle">Hello</text>
</svg>
✅ Fixed: attribute removed entirely (uses default start)
<svg width="200" height="200">
<g>
<text x="100" y="100">Hello</text>
</g>
</svg>
✅ Using CSS to style text inside a group
If you want all text elements within a group to share the same alignment, apply the style via CSS rather than a presentation attribute on <g>:
<svg width="200" height="200">
<style>
.centered-text text {
text-anchor: middle;
}
</style>
<g class="centered-text">
<text x="100" y="50">First line</text>
<text x="100" y="100">Second line</text>
</g>
</svg>
✅ Valid use on other text-related elements
The text-anchor attribute can also be applied to <tspan> and <textPath>:
<svg width="300" height="100">
<text x="150" y="50" text-anchor="start">
Start-aligned
<tspan x="150" dy="30" text-anchor="end">End-aligned span</tspan>
</text>
</svg>
The <pattern> element lives inside <svg>, and SVG is an XML-based language. Unlike regular HTML — where id values follow relatively relaxed rules — SVG content must comply with XML 1.0 naming conventions. This means id values have stricter character and formatting requirements than you might be used to in plain HTML.
XML 1.0 Name Rules
An XML 1.0 name (used for id attributes in SVG) must follow these rules:
- First character must be a letter (
A–Z,a–z) or an underscore (_). - Subsequent characters can be letters, digits (
0–9), hyphens (-), underscores (_), or periods (.). - Spaces and special characters like
!,@,#,$,%,(,), etc. are not allowed anywhere in the name.
Common mistakes that trigger this error include starting an id with a digit (e.g., 1pattern), a hyphen (e.g., -myPattern), or a period (e.g., .dotPattern), or including characters like spaces or colons.
Why This Matters
- Standards compliance: SVG is parsed as XML in many contexts. An invalid XML name can cause parsing errors or unexpected behavior, especially when SVG is served with an XML MIME type or embedded in XHTML.
- Functionality: The
<pattern>element'sidis typically referenced viaurl(#id)infillorstrokeattributes. An invalididmay cause the pattern reference to silently fail, leaving elements unfilled or invisible. - Cross-browser consistency: While some browsers are lenient with invalid XML names, others are not. Using valid names ensures consistent rendering across all browsers and environments.
How to Fix
Rename the id value so it starts with a letter or underscore and contains only valid characters. If you reference this id elsewhere (e.g., in fill="url(#...)" or in CSS), update those references to match.
Examples
❌ Invalid: id starts with a digit
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="1stPattern" width="10" height="10" patternUnits="userSpaceOnUse">
<circle cx="5" cy="5" r="3" fill="blue" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#1stPattern)" />
</svg>
❌ Invalid: id starts with a hyphen
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="-stripe-bg" width="10" height="10" patternUnits="userSpaceOnUse">
<rect width="5" height="10" fill="red" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#-stripe-bg)" />
</svg>
❌ Invalid: id contains special characters
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="my pattern!" width="10" height="10" patternUnits="userSpaceOnUse">
<circle cx="5" cy="5" r="3" fill="green" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#my pattern!)" />
</svg>
✅ Valid: id starts with a letter
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="firstPattern" width="10" height="10" patternUnits="userSpaceOnUse">
<circle cx="5" cy="5" r="3" fill="blue" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#firstPattern)" />
</svg>
✅ Valid: id starts with an underscore
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="_stripe-bg" width="10" height="10" patternUnits="userSpaceOnUse">
<rect width="5" height="10" fill="red" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#_stripe-bg)" />
</svg>
✅ Valid: Using letters, digits, hyphens, and underscores
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="dot-grid_v2" width="10" height="10" patternUnits="userSpaceOnUse">
<circle cx="5" cy="5" r="3" fill="green" />
</pattern>
</defs>
<rect width="200" height="200" fill="url(#dot-grid_v2)" />
</svg>
Note that this same XML 1.0 naming rule applies to id attributes on all SVG elements — not just <pattern>. If you see similar errors on elements like <linearGradient>, <clipPath>, or <filter>, the same fix applies: ensure the id starts with a letter or underscore and uses only valid characters.
A data: URI in the src attribute of an <img> element can't contain a raw <, so inline SVG markup in that URI needs its angle brackets written as %3C and %3E.
A data: URI puts the file itself inside the URL, and everything after the comma has to be made of URL characters. Angle brackets, spaces and double quotes aren't. The validator stops at the first illegal character, which in inline SVG is the < that opens the <svg> tag. The ta: in the message is just the end of data:. The validator quotes the scheme, not the spot where the bad character sits.
This markup often comes from lazy-loading scripts. An empty SVG with only width and height sits in src as a placeholder that reserves the image's box, while the real file waits in data-src or data-srcset. Browsers usually render the placeholder anyway, but the value is still an invalid URL.
Encoding only the angle brackets isn't enough: the validator then reports the first space. Write < as %3C, > as %3E and each space as %20, and use single quotes inside the SVG or encode double quotes as %22. Also remove the ;utf8 after the media type, or write it as ;charset=utf-8. Once the brackets are encoded, the validator rejects a parameter with no value. In JavaScript, encodeURIComponent() produces a valid string, and a base64-encoded SVG with ;base64 before the comma avoids the problem too.
Invalid example
<img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='200'></svg>" data-src="photo.jpg" alt="Product photo">
Valid example
<img src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='300'%20height='200'%3E%3C/svg%3E" data-src="photo.jpg" alt="Product photo">
A data: URI in the src attribute of an <img> element can't contain literal spaces, so an inline SVG in that URI needs every space written as %20.
The data: scheme, defined in RFC 2397, puts the file itself in the attribute value. The data after the comma may only contain URL characters, and a space isn't one of them. The ta: in the message is the end of data:. The validator quotes the scheme rather than the position of the space, so the space can be anywhere in the value.
Inline SVG is the usual cause. SVG markup needs a space between the element name and each attribute, as in <svg xmlns='...' width='300'>, and encoding the angle brackets as %3C and %3E leaves those spaces alone. A common case is an empty SVG with only width and height, used as a placeholder that holds the image's box until the real file loads.
Browsers usually render the image anyway, but the value is still an invalid URL. Replace every space with %20, or base64-encode the SVG and add ;base64 before the comma. In JavaScript, encodeURIComponent() converts the spaces to %20, along with the angle brackets and double quotes. If the SVG is large or reused, save it as a file and point src at that file.
Invalid example
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='200'/%3E" alt="">
Valid examples
<img src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='300'%20height='200'/%3E" alt="">
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMDAiIGhlaWdodD0iMjAwIi8+" alt="">
The version attribute on the <svg> element is obsolete in SVG 2 and is no longer recognized as a valid attribute by the W3C HTML validator.
The version attribute was used in SVG 1.0 and SVG 1.1 to indicate which specification the SVG content conformed to, with values like "1.0" or "1.1". However, SVG 2 — which is the version used when SVG is embedded in HTML5 documents — dropped this attribute entirely. It never had any practical effect on how browsers rendered SVG content, so removing it is safe and has no impact on functionality.
Similarly, the baseProfile attribute and the xmlns:xlink namespace declaration are also obsolete when using inline SVG in HTML5. You can safely remove all three.
Bad Example
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
Fixed Example
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
If your SVG files are exported from tools like Illustrator, Inkscape, or Figma, they often include the version attribute by default. You can safely strip it out manually or use an SVG optimizer like SVGO to clean up unnecessary attributes automatically.
The xmlns:xlink attribute on inline SVG accepts only one value, http://www.w3.org/1999/xlink.
The message calls the attribute xmlns:link, but the one to look for in your markup is xmlns:xlink. It declares the XLink namespace, which SVG 1.1 used for attributes such as xlink:href. A namespace URI is a fixed name that the browser never loads, so it has to match the specification character for character. A different year, a trailing slash, https instead of http, or a path segment rewritten by a build tool or a search and replace all trigger this error.
In an HTML document you don't need the declaration at all. The HTML parser puts xlink:href and the other xlink: attributes in the XLink namespace by itself, and SVG 2 lets you write plain href on <use>, <image> and <a>. Either correct the value or remove the attribute and switch xlink:href to href.
Invalid example
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/2000/xlink" viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#icon-star"></use>
</svg>
Valid example
Correct the namespace URI:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#icon-star"></use>
</svg>
Or drop the declaration and use href:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<use href="#icon-star"></use>
</svg>
On <svg> and the elements inside it, the xmlns attribute can only hold the SVG namespace, http://www.w3.org/2000/svg.
When the HTML parser reads inline SVG, it places <svg> and its descendants in the SVG namespace by itself, whatever xmlns says. The main exception is content inside <foreignObject>, which is parsed as HTML. Because the attribute can't change the namespace, the HTML standard makes any other value a parse error, whether it sits on the <svg> element or on a child such as <g> or <path>. A trailing slash or the XHTML namespace triggers it just like an unrelated URI does.
Design tools are a common source. Adobe Illustrator can export a <metadata> block holding an <sfw> element declared in its own Save for Web namespace, http://ns.adobe.com/SaveForWeb/1.0/. In a standalone .svg file, which is parsed as XML, that declaration puts <sfw> in Adobe's namespace. Pasted into HTML, the declaration has no effect and <sfw> becomes an unknown SVG element, so the validator also reports sfw and slices as unknown elements. Browsers don't render <metadata>, so deleting the block leaves the graphic unchanged, and SVG optimizers such as SVGO remove it by default.
For the attribute itself, either set it to exactly http://www.w3.org/2000/svg or remove it, because inline SVG in HTML doesn't need it.
Invalid example
<svg viewBox="0 0 24 24" width="24" height="24">
<metadata>
<sfw xmlns="http://ns.adobe.com/SaveForWeb/1.0/">
<slices></slices>
</sfw>
</metadata>
<circle cx="12" cy="12" r="10" fill="teal"/>
</svg>
Valid example
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<circle cx="12" cy="12" r="10" fill="teal"/>
</svg>
XML processing instructions are a feature of XML, not HTML. They begin with <? and end with ?>, and are used in XML documents to carry instructions for applications processing the document. The most common example is the XML declaration: <?xml version="1.0" encoding="UTF-8"?>. While these are perfectly valid in XML, the HTML parser does not recognize them. When the parser encounters <?, it doesn't know how to handle it and treats it as a bogus comment, which leads to unexpected behavior and this validation error.
This matters for several reasons. First, standards compliance — HTML5 has a clearly defined parsing algorithm, and processing instructions are not part of it. Second, browser behavior becomes unpredictable — different browsers may handle the unexpected <? content differently, potentially exposing raw code or breaking your layout. Third, if server-side code like PHP leaks into the output, it can expose sensitive logic or configuration details to end users.
There are three common causes of this error:
1. Inlining SVG files with their XML declaration. When you copy the contents of an .svg file and paste it directly into HTML, the file often starts with an XML declaration and possibly a <?xml-stylesheet?> processing instruction. These must be removed — only the <svg> element and its children should be included.
2. Unprocessed server-side code. Languages like PHP use <?php ... ?> (or the short tag <? ... ?>) syntax. If the server isn't configured to process PHP files, or if a .html file contains PHP code without being routed through the PHP interpreter, the raw <?php tags end up in the HTML sent to the browser.
3. Copy-pasting XML content. Other XML-based formats (like RSS feeds, XHTML fragments, or MathML with XML declarations) may include processing instructions that aren't valid in HTML.
How to Fix It
- For inline SVGs: Open the SVG file in a text editor and copy only the
<svg>...</svg>element. Remove the<?xml ...?>declaration and any other processing instructions that precede the<svg>tag. - For PHP or other server-side code: Ensure your server is properly configured to process the files. Check that the file extension matches what the server expects (e.g.,
.phpfor PHP files). Verify that the server-side language is installed and running. - For other XML content: Strip out any
<?...?>processing instructions before embedding the content in HTML.
Examples
❌ Inline SVG with XML declaration
<body>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
</body>
The <?xml version="1.0" encoding="UTF-8"?> line triggers the error.
✅ Inline SVG without XML declaration
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue" />
</svg>
</body>
❌ Unprocessed PHP code in HTML output
<body>
<h1>Welcome</h1>
<p><?php echo "Hello, World!"; ?></p>
</body>
If the server doesn't process the PHP, the raw <?php ... ?> ends up in the HTML and triggers this error.
✅ Properly processed output (or static HTML equivalent)
<body>
<h1>Welcome</h1>
<p>Hello, World!</p>
</body>
❌ SVG with an XML stylesheet processing instruction
<body>
<?xml-stylesheet type="text/css" href="style.css"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<rect width="50" height="50" fill="red" />
</svg>
</body>
✅ SVG without the processing instruction
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
<rect width="50" height="50" fill="red" />
</svg>
</body>
In HTML, use standard <link> or <style> elements in the <head> for stylesheets instead of XML processing instructions.
An <svg> element can contain child elements and the whitespace between them, but no text of its own.
The most common cause is a typo in the start tag. An extra >, as in <svg viewBox="0 0 24 24">>, closes the tag and leaves the second > behind as a text character inside the SVG. The validator also reports this error for a entity, a stray word, or fallback text such as "Close" written between the child elements. Line breaks and indentation between elements are fine.
Browsers don't draw text that sits directly inside <svg>, so the graphic looks correct and the mistake is easy to miss. To show text in the graphic, put it in a <text> element. To give the graphic an accessible name, add a <title> element inside the <svg>.
Text placed directly inside a <g> or another SVG container triggers the same kind of error, naming that element instead of svg.
Invalid example: extra > in the start tag
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">>
<path d="M5 15.5L12 8.5L19 15.5" fill="none" stroke="currentColor" stroke-width="2" />
</svg>
Valid example
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path d="M5 15.5L12 8.5L19 15.5" fill="none" stroke="currentColor" stroke-width="2" />
</svg>
Invalid example: text used as a label
<svg viewBox="0 0 24 24" width="24" height="24">
Close
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" />
</svg>
Valid example: label in a title element
<svg viewBox="0 0 24 24" width="24" height="24" role="img">
<title>Close</title>
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" />
</svg>
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