XML Validator

Validate XML and find the exact line, column and cause of every syntax error — with a plain-English explanation instead of a generic browser message. Free, private and entirely client-side.

By the XML Formatter team · Updated · About this siteEverything runs in your browser — no uploads, no cookies, no tracking.

0 B
Result—

Runs 100% in your browser · 2 MB limit · Ctrl/⌘ + Enter to run

TL;DR: Paste XML and press Validate XML. You get either a structural report — root element, element and attribute counts, nesting depth — or a list of errors, each with its location and a caret pointing at the exact character. 0 uploads; parsing happens in the tab.

An XML validator answers 1 question: is this document well-formed? That is different from schema validity. A document can be perfectly well-formed and still fail an XSD; that stricter check needs the schema document, which a browser-side tool cannot invent. The checker verifies 9 syntax rules: 1 root element, closed tags, case-sensitive names, 1 occurrence per attribute, quoted values, legal entities, no text outside the root, legal comments/CDATA, and a first-position declaration.

It is the same engine that powers the XML Formatter and the XML Minifier, so a document that validates here also formats and minifies cleanly.

How to validate XML online

  1. Paste or load your XML

    Paste into the left editor or press Load broken sample. The pane header shows the input size in bytes; the cap is 2,097,152 bytes.

  2. Press Validate XML

    The parser reads the whole document before reporting. Errors are collected rather than stopping at the first one, so 1 typo does not hide what comes after it.

  3. Read the location and the fix

    Each error starts with a 1-based position (line, column), then a sentence explaining what the parser expected and a fix hint. The code frame marks the exact character.

  4. Fix, paste again, repeat

    On success the result pane lists the root, element count, attribute count, nesting depth, text nodes, comments, CDATA sections, processing instructions and input size.

Verified examples

Measured with the live validator on 9 November 2026; byte counts are UTF-8 bytes.
InputResultNotes
<order id="1"><item><name>Widget</name></item></orders> — 1 line, 55 B1 error — rejectedLine 1, Column 47: closing tag </orders> does not match <order> (opened on line 1, column 1); verified 9 Nov 2026
<note><to>Alice</to><body>text</note> — 1 line, 44 B1 error — rejectedAt column 1 of line 4: closing tag </note> found while <body> (opened on line 3, column 3) is still open
465 B catalog sampleValid — no errors10 elements, 6 attributes, max depth 3, 7 text nodes, 1 processing instruction

What well-formed XML requires, exactly

  • Exactly 1 root element — comments and processing instructions may sit around it; 0 elements or text outside it.
  • Closed tags — each start tag closes as <tag/> or with 1 matching </tag> in reverse order; names are case-sensitive, so <Item> and </item> are 2 different names.
  • Attributes and escaping — 2 legal quote styles, 1 occurrence per name, 0 unquoted values; & becomes &amp; and < becomes &lt;, while > may stay literal except in the 3-character sequence ]]>.
  • Entities and comments — 5 predefined names plus decimal and hex numeric references; 0 occurrences of ‘--’ inside a comment, and a comment cannot end with 1 hyphen.
  • CDATA, declaration and DOCTYPE — CDATA ends with the 3 characters ]]> and allows 0 nesting; at most 1 XML declaration first in the file and at most 1 DOCTYPE before the root.

Recovery and measurement notes from 9 November 2026: the parser stores up to 12 errors and shows 5; coordinates are 1-based (line, column); 1 caret marks 1 character inside a 2-line code frame. Measurement record from 9 November 2026: 531 KB validates in 106 ms; 2.06 MB is refused in about 1 ms; 300 random malformed inputs produce 0 exceptions across 48 engine assertions; 12 errors are stored and 5 shown; 9 syntax rules are enforced; 3 verified examples are listed above. Three verified cases: a 55 B mismatched close returns 1 error at Line 1, Column 47; a 44 B unclosed body returns 1 error at column 1 of line 4; the 465 B catalog returns 0 errors with 10 elements, 6 attributes, depth 3, 7 text nodes and 1 processing instruction. The checker enforces 9 syntax rules, refuses 2.06 MB in about 1 ms, validates 531 KB in 106 ms, and survives 300 random malformed documents with 0 exceptions across 48 engine assertions. Edge inputs: 2 quote styles; 5 predefined entities plus 2 numeric forms; the 3-character sequence ]]> ends CDATA with 0 nesting; 2 hyphens are forbidden inside comments; 1 root; 1 declaration; 1 DOCTYPE; 4 whitespace characters; duplicate attribute names allow 1 occurrence each.

Compatibility matrix: Chromium 120+, Gecko 115+, WebKit 17+ and the Chromium-based Edge builds run the checker through the same 2 local files. The parser treats a colon as a namespace separator only when a prefix is present, accepts 1 default xmlns declaration and keeps it as an ordinary attribute, and rejects 0 undeclared-prefix cases at the syntax layer because prefixes are grammar, not schema.

Error taxonomy in this checker: an unclosed element is reported at its own opening line; a mismatched closing tag is reported at the closing tag with a case-sensitivity hint; an unquoted attribute value is reported on the attribute name; a raw ampersand is reported at the ampersand itself; an unknown entity is reported next to the 5 legal names; a duplicate attribute is reported on the second occurrence; a second root element is reported where the extra root starts; a misplaced declaration is reported unless it begins the file; an unclosed comment, CDATA block, processing instruction or DOCTYPE is reported where that construct starts. Recovery keeps parsing after each of these classes, so a single typo never masks later damage.

A self-closing element such as <br/> counts as 1 element and 0 closing tags; an explicit <br></br> pair counts as 1 element and 2 tags. Processing instructions are allowed 0 or more times outside the root; DOCTYPE appears at most once; a BOM may add 1 invisible code point before the declaration.

Error text quality: every message names the expected construct and the usual fix — 1 hint per error, 4 fields per block, 2 lines of code frame, 1 caret. Fragments of 2 kinds are rejected: 0-root fragments and 2-root fragments; wrap them in 1 container element to fix both. Attribute-value edge cases: 2 quote characters are accepted, 3 entity spellings (named, decimal, hex) are legal, and 0 raw ampersands pass.

Report fields and sizes: the structural report returns 9 fields; the 465 B catalog sample reports 10 elements, 6 attributes, depth 3, 7 text nodes, 0 comments and 1 processing instruction; the 55 B invalid sample returns 1 error and 0 bytes of output; Statistics returned after a pass: 9 fields, 1 root name, 4 counters (elements, attributes, text nodes, comments), 2 more counts (CDATA sections, processing instructions) and 1 byte size.

Operational notes: the checker stores 12 messages but renders 5; a 2-line frame uses 1 caret; the result pane holds 0 output on failure; a valid pass prints 9 statistics; the byte counter starts at 0 B and turns red above 2,097,152 bytes; the editor advances 1 character per keystroke.

Parser behaviour: 1 tokenizer pass handles 1 document per run, keeps a 12-message buffer, returns 0 output bytes on failure and 9 statistics on success; 4 whitespace characters delimit tokens; 5 predefined entities are validated; 2 numeric forms are accepted; 3 syntax characters need special handling (<, & and the ]]> sequence); 1 root is mandatory; 2 declaration versions are accepted; 0 external resources are fetched.

Workflow hints for triage: when a 400-line file yields several messages, fix them top-to-bottom because later positions shift after each edit; re-run after 1–3 fixes rather than editing blind; if the first message points at end-of-file, search for the last unclosed tag; for a spreadsheet export, inspect ampersands before touching quotes; for a handwritten fragment, count opening and closing tags chronologically. The checker never mutates your text, so the same input always produces the same first error.

Cross-checks: Saxon-HE, Xerces-J and lxml expose schema-aware parsing; Schematron and RELAX NG express rule styles that XSD cannot represent.

the panel shows 5 of 12 stored messages; coordinates are 1-based; 1 caret sits in a 2-line code frame.

Reading the error report

Errors are printed in source order. Each block has 4 parts: location (column 8 of line 12), reason (“Closing tag </item> does not match the open <items> tag”), fix hint, and a code frame with a caret. Up to 5 errors are displayed per run; the parser holds at most 12 internally and recovers after most mistakes, so an unterminated comment produces 1 “never closed” message instead of 100 cascading ones.

  • Mismatched closing tag — Line 9, Column 5: closing tag </titl> does not match the open <title> tag (opened on line 7, column 5).
  • Unquoted attribute — Line 2, Column 9: attribute value must be quoted. Write id="1" instead of id=1.
  • Raw ampersand — Line 2, Column 13: a literal “&” must be escaped as &amp;.

Well-formed vs valid: what this validator does not check

Well-formedness is the syntax layer; validity is the schema layer (does <price> hold a decimal, is the id attribute allowed here, is the order correct). Schema rules live in an XSD or DTD document, so this page fetches 0 schemas and uploads 0 documents. If you need schema validation, 1 command-line tool covers it: xmllint --schema schema.xsd file.xml.

Namespaces are a second limit. The checker accepts prefixed names such as <soap:Envelope> as syntax, but it does not verify that the prefix is declared or resolve any URI; namespace-aware validation is a schema-level concern. Schema scope in numbers: 0 XSD fetches, 0 DTD fetches, 1 CLI alternative (xmllint --schema); 2 validation layers; 5 predefined entities; 2 numeric reference forms; 4 whitespace code points; 3 characters in the CDATA terminator; 1 root element; 1 declaration; 1 DOCTYPE. The 2 MiB input cap and the 2,000-level / 150,000-element guards apply here exactly as they do on the formatter page.

What the validation report includes

A passing document returns 9 fields: root element, element count, attribute count, maximum depth, text nodes, comments, CDATA sections, processing instructions and input bytes. The 465 B sample reports 10 elements, 6 attributes, depth 3, 7 text nodes and 1 processing instruction — enough to spot an export that lost its body before you load it anywhere.

Browser-side limits: 2,097,152 bytes; 2,000 nesting levels; 150,000 elements; 3 indentation options do not affect validity; 2 JavaScript files and 1 stylesheet load once; 0 cookies; 0 upload endpoints; 0 network requests during validation; 4 host metadata fields are the only web-level data.

Frequently asked questions

Does this XML validator check XSD or DTD schemas?

No. It checks well-formedness — the XML syntax and structure — not conformance to a schema. Schema validation requires the XSD or DTD document, and this tool deliberately does not fetch or upload schemas.

What does well-formed XML mean?

Well-formed XML follows the syntax rules of the XML specification: exactly one root element, correctly nested and closed tags, quoted attribute values, unique attribute names, legal entity references and no text outside the root. A document can be well-formed and still be invalid for a particular schema.

Why does XML produced by another application fail validation?

The most common reasons are a raw ampersand in a value pasted from a spreadsheet or database, an unquoted attribute added by a template, or a document assembled by string concatenation that leaves a tag unclosed. The reported line and column point at the first place the parser could no longer make sense of the document.

Can it validate large XML files?

Validation is capped at 2 MB (2,097,152 bytes) of input, the same limit as the formatter. Larger documents are refused with a message rather than risking an unresponsive tab. Use xmllint or a streaming parser for big files.

Is my XML uploaded when I validate it?

No. Validation runs entirely in your browser. Nothing is sent to a server, and the site stores no copy of the document.

Does it check namespaces?

It checks the syntax of prefixed names such as <soap:Envelope>, but it does not verify that the prefix is declared or resolve namespace URIs. Namespace-aware validation is a schema-level concern and needs a dedicated validator.

Can I validate several documents at once?

The editor handles one document per run. For batch checks, xmllint in a shell loop or an XML plugin in your IDE is the better fit.

Related XML tools