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.
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.
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:svg violates these rules.
- Serialization issues: If a browser parses the HTML and then re-serializes it (e.g., via innerHTML), the xmlns:svg attribute 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" alongside xmlns="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 the xmlns:svg attribute.
- 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, even xmlns is 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).
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:o attributes 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, and xmlns: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.
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.
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 the xmlns:svg attribute.
- 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., use href instead of xlink: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.
Empty aria-labelledby on the <svg> is invalid because it must reference one or more existing IDs with non-empty, non-whitespace text.
The aria-labelledby attribute takes a space-separated list of element IDs (IDREFS). Each ID must exist in the document and point to elements that provide an accessible name. On <svg>, this is commonly a <title> or other visible text element. If you have no label to reference, either remove aria-labelledby or provide a valid referenced element. Alternatively, use the aria-label attribute with a text string. Do not leave aria-labelledby empty, and ensure IDs are unique and match exactly (case-sensitive). Examples: reference a <title> with an id, or use aria-label directly on the <svg>.
HTML Examples
Example showing the issue
<svg role="img" aria-labelledby="">
<use href="#icon-star"></use>
</svg>
Fixed examples
<!-- Option A: Reference a title by ID -->
<svg role="img" aria-labelledby="starTitle">
<title id="starTitle">Favorite</title>
<use href="#icon-star"></use>
</svg>
<!-- Option B: Use aria-label instead (no referenced IDs needed) -->
<svg role="img" aria-label="Favorite">
<use href="#icon-star"></use>
</svg>
<!-- Option C: Decorative icon (no name) -->
<svg aria-hidden="true" focusable="false">
<use href="#icon-star"></use>
</svg>
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 xmlns on 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 .svg files).
- 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 xmlns value with "http://www.w3.org/2000/svg".
- Remove the attribute entirely: Since xmlns is 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.
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, so text-anchor has no meaningful effect on it. While CSS inheritance might cause child text elements to pick up styles from a parent <g>, the text-anchor presentation attribute is only valid on elements that actually render text content.
- Standards compliance: The SVG specification explicitly defines which elements accept text-anchor and 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, or end. If you want the default behavior (left-aligned for LTR text), simply omit the attribute entirely, as start is the default.
- If you need to set text-anchor for 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’s id is typically referenced via url(#id) in fill or stroke attributes. An invalid id may 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.
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., .php for 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.
Ready to validate your sites?
Start your free trial today.