Common causes
1. An attribute value without quotes
HTML allows port=8080; XML requires every attribute value in single or double quotes.
<server port=8080 host="localhost"/><server port="8080" host="localhost"/>2. A raw < in text content
< always starts a tag in XML. Write it as < in text and attribute values (and > as > for symmetry), or wrap code in a CDATA section.
<limit>maxConnections < 100</limit><limit>maxConnections < 100</limit>3. An invalid element or attribute name
Names must start with a letter, underscore or colon, and cannot contain spaces. Keys converted from JSON or spreadsheet headers often break this rule.
<user><2fa>true</2fa><first name>Ada</first name></user><user><twoFactor>true</twoFactor><firstName>Ada</firstName></user>4. Control characters in the text
XML 1.0 forbids most characters below U+0020, such as the vertical tab and form feed Word and old databases produce. Even  is not allowed. Remove them before generating the XML.
<note>Line oneLine two</note><note>Line one Line two</note>Frequently asked questions
Why is the message so vague?
Expat reports every illegal character with the same error code, XML_ERROR_INVALID_TOKEN. The line and column are accurate, so look exactly there; PasteKit explains which rule the character breaks.
Can a wrong encoding cause this error?
Yes. A file saved as Windows-1252 but declared or read as UTF-8 contains byte sequences that are not valid UTF-8, and expat reports them as an invalid token. Re-save the file as UTF-8 or declare the real encoding.
What about a raw & in text?
Expat reports a bare & as not well-formed (invalid token) too. See unescaped ampersands in XML for that case.