“XML parsing error: not well-formed” means the parser gave up on syntax, not on your schema. One root, matching tags, quoted attributes and escaped & < > are required. Paste the document into the XML Validator to get the first error's exact line and column; the XML Formatter uses the same check before it pretty-prints. Nothing is uploaded.
What “not well-formed” actually asserts
XML 1.0 splits two questions that people mash together. Well-formed means the document is legal XML: a single root, every start tag has a matching end tag, attribute values are quoted, and the five markup characters are escaped. Valid means the document also matches a DTD or XSD. Firefox's “XML Parsing Error: not well-formed”, Chrome's “error on line X at column Y”, Java's SAXParseException and Python's xml.etree.ElementTree.ParseError are almost always the first kind. Fix well-formedness before you argue with a schema.
A well-formedness checker reports exactly one error per run. After a mismatched tag the rest of the document is unparseable by definition, so the line number is where the parser stopped, not always where you made the mistake. Look at that position and one tag backwards.
The four mistakes that cause nearly every failure
- An unclosed or mismatched tag.
<Book>…</book>is not well-formed: XML names are case-sensitive. A missing</item>is usually reported at the parent's close, not on the line you forgot. - A raw ampersand.
Smith & Comust be writtenSmith & Co. The same rule applies to<and>in text. Attribute values that contain quotes need"or a different wrapping quote. - More than one root element. A document that is
<a/><b/>is a fragment, not a document. Wrap the siblings or split the file. SOAP envelopes already have one root; the error then is usually a second payload pasted after it. - An illegal character at the start. A UTF-8 BOM, a smart quote from email, or a stray byte before
<?xmlshows up as line 1, column 1.
A broken fragment and the fix
This catalog excerpt fails for three reasons at once:
<catalog>
<book id=bk101>
<title>Structure & Interpretation</title>
</Book>
<catalog>The id attribute is unquoted, the ampersand in the title is raw, the end tag uses different case from the start tag, and the root is never closed (the last line opens a second catalog). A parser will usually complain about the unquoted attribute first. Fix that, validate again, and the next error appears. The well-formed form is:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101">
<title>Structure & Interpretation</title>
</book>
</catalog>After it validates, Format re-indents without changing text, attributes, comments or CDATA. Minify is the opposite action: it only removes whitespace between tags.
How to read the line and column
Parsers report where they gave up. A missing comma-equivalent in XML is a missing close tag: the error lands on the next unexpected token. If the status bar says “Line 12, column 3”, open the file at that line, then scan upward for the last unclosed start tag. The validator highlights the reported line in the gutter so you do not have to count.
An error at line 1, column 1 on a document that “looks fine” is usually invisible: a BOM (EF BB BF), a 0x00 from a UTF-16 file saved as UTF-8, or a curly quote “ instead of ". Re-save as UTF-8 without BOM, or paste into the validator and look at the first character in a hex view if you have one.
External entities are not the fix
A DOCTYPE with SYSTEM "http://…" is a classic XXE shape. A browser or server that resolves it will fetch that URL while parsing. LocalFirstTools never fetches DTDs or external entities, so an XXE payload cannot load anything here, and a missing DTD is also not why your document is “not well-formed”. If a gateway rejects the file after it validates here, the gateway is doing schema or business-rule checks on top.
Language-specific wording
- Browsers: Firefox prints “XML Parsing Error: not well-formed” plus a column. Chrome's XML viewer prints “This page contains the following errors” and a location.
- Java:
org.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 3. - Python:
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 12, column 2. - SOAP / SAML / e-invoice gateways: often wrap the same parser error in a fault string. Extract the inner message and validate the payload alone.
Once the document is well-formed, convert it if you need JSON fixtures with XML → JSON, or keep working in XML with the formatter. Related reading: JSON vs YAML vs XML.
A five-minute checklist
- Copy only the XML, not the HTTP headers or the email wrapper around it.
- Paste it into the XML Validator. If the status is green, the gateway's complaint is schema or business rules, not well-formedness.
- If it is red, read the line and column, fix that token, validate again. Repeat.
- Check the first bytes if the error is at 1:1: re-save as UTF-8 without BOM, replace smart quotes, confirm the file is not UTF-16.
- When it is green, format it for the review and, if you need fixtures, convert a copy with XML → JSON. Keep the original XML if byte identity matters.
Namespaces look scary and almost never cause “not well-formed”. <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> is fine. An unbound prefix is a namespace error some parsers report as a fatal error and others as well-formed-but-invalid; add the xmlns: declaration on an ancestor if the status names an undeclared prefix. Processing instructions (<?xml-stylesheet …?>) and comments can sit before the root, but text cannot. A stray “Yes,” from a mail client above the declaration is line 1, column 1 again.
Self-closing tags (<price/> vs <price></price>) are both well-formed. Empty elements are not the bug. Mixed content is well-formed too: <note>See <ref id="a"/> above</note> is legal XML and the formatter will leave that inner whitespace alone when xml:space="preserve" is set. If a pretty-printer then “breaks” a poem or a signature block, the printer was collapsing significant space; this site's formatter does not.
You do not need a server, a Java toolchain or xmllint installed to get through the first error. Those tools are excellent once you are in a repo. For a paste from a ticket, the local validator is enough, and it will not fetch the DTD a hostile payload pointed at.