Common XSD Validation Errors Explained With the Fix for Each
Ten XSD validation messages from libxml2, exactly as printed, what each one means in the document and the smallest change that makes it validate.

An XSD error message tells you three things: which element or attribute, which rule, and what the validator saw. It does not tell you what to do. After enough of them you recognize the families, and most of the fixes take a minute. This is a reference to the ten that account for nearly everything I met, each one produced from a real test document and printed exactly as xmllint wrote it.
1. The element is in the wrong place
Element 'status': This element is not expected. Expected is ( customer ).Meaning. A sequence demands its children in the declared order. The validator is at a point where only customer is allowed, and it found status. It does not mean status is invalid in the document; it is invalid here.
Fix. Reorder the elements in the document, or, if the order is not meant to matter, change the schema from xs:sequence to xs:all (each element at most once) or loosen it. Check the sender's generator before you do either: an order that changes with the library they use is a bug on their side.
2. A required child is missing
Element 'order': Missing child element(s). Expected is one of ( note, item ).Meaning. The parent ended before the validator was satisfied. The list holds everything acceptable next, which includes note because it is optional, so the real gap is item. Read it as "I stopped seeing children and I needed at least one of these".
Fix. Add the missing element, or make it optional with minOccurs="0" if the schema was stricter than the business.
3. An element nobody declared
Element 'coupon': This element is not expected. Expected is ( item ).Meaning. The same message as 1, but here the element really is unknown, and the validator is saying what it would take instead. How to tell them apart: look up the element name in the schema. If it is there, the order is wrong. If it is not, the sender has added something.
Fix. If the extra element is legitimate, add it to the schema as optional. If you want to tolerate additions from senders without breaking, declare an xs:any wildcard with processContents="lax" at the extension point, and decide in advance that unknown elements are ignored.
4. A value that is not the right type
Element 'item': '9,50' is not a valid value of the atomic type 'xs:decimal'.
Element 'order', attribute 'id': 'x1' is not a valid value of the atomic type 'xs:integer'.
Element 'item', attribute 'qty': '0' is not a valid value of the atomic type 'xs:positiveInteger'.Meaning. The text is not in the lexical form of the type. A decimal needs a period, no thousands separators, no currency symbol; an integer only digits with an optional sign; a positive integer is above zero. The message names the built-in type, and for a type you derived (Price based on xs:decimal), you may see the base type in the message.
Fix. In the document, correct the value. In the schema, if the field really can hold text such as n/a, give it a union type or use xs:string and check elsewhere. For dates, the type is strict: xs:date wants 2026-10-01, not 10/01/2026.
5. A value outside an enumeration
Element 'status': [facet 'enumeration'] The value 'PAID' is not an element of the set {'new', 'paid', 'shipped'}.Meaning. The value is compared exactly, case and all. This is the friendliest message because it prints the allowed set.
Fix. Change the value, or add it to the enumeration if the business has added a status. Adding values to an enumeration is a change that old documents survive and old schemas do not (testing feed compatibility before a schema change).
6. A value that fails a pattern
Element 'item', attribute 'sku': [facet 'pattern'] The value 'a-1' is not accepted by the pattern '[A-Z]-[0-9]{3}'.Meaning. The whole value must match the regular expression. There is no partial match, and the expression uses XSD's dialect.
Fix. The message gives the pattern and the value and leaves the comparison to you: here the letter is lowercase and the digits too few. Trailing spaces cause the same message with a value that looks right on screen, so print it with repr() before you decide the pattern is wrong. Whitespace handling is controlled by the type: xs:string keeps it, xs:token collapses it.
7. A required attribute is missing
Element 'order': The attribute 'id' is required but missing.Meaning. The schema says use="required" and the document has no such attribute. The cause is often a typo on the attribute name in the sender's file, in which case you would also see an "attribute not allowed" message for the misspelled one.
Fix. Add the attribute, or make it optional.
8. An attribute that is not allowed
Element 'item', attribute 'color': The attribute 'color' is not allowed.Meaning. The schema does not declare it for this element.
Fix. Declare it, or allow arbitrary attributes with xs:anyAttribute.
9. The root is not declared
Element 'order': No matching global declaration available for the validation root.
Element '{urn:shop}orders': No matching global declaration available for the validation root.Meaning. The schema has no top-level declaration for this root element name in this namespace. Only elements declared as direct children of xs:schema can be roots. The second form, with a name in curly braces, shows the document is in a namespace the schema does not use.
Fix. Compare three things: the root element name, the document's xmlns, and the schema's targetNamespace. In the first example the file's root was order and the schema's was orders. In the second, the document added xmlns="urn:shop" and the schema had none. Either the schema needs the targetNamespace or the document should drop the namespace. The rules are in how XML namespaces work.
10. The file is not well-formed
e_wf.xml:4: parser error : Opening and ending tag mismatch: order line 3 and ordersMeaning. This is not a schema error at all, and it is on the list because it appears in the same output. The parser stopped before the validator had a tree.
Fix. Repair the syntax first. See fixing XML parse errors fast and mismatched tag errors in large XML.
How to work through a list of errors
Fix syntax errors first. Nothing else is reliable until the file parses.
Fix the first schema error, then rerun. A structural error can cause a cascade of messages after it. The
lxmlerror log shows more than one at a time, but later ones may be consequences of the first.Read the element name, then the rule, then the value. The element tells you where, the facet or type says what kind of rule, and the quoted value shows what was found.
Look at the raw bytes of a value you cannot explain. A non-breaking space, a trailing newline or a zero-width character looks like nothing on screen and fails a pattern.
Decide whether the document or the schema is wrong. Both happen. A schema that rejects a value the business accepts is a defect in the schema.
Related reading
For the commands that produced these, see validating XML against XSD with xmllint and validating XML in Python with lxml and XSD. The cluster overview is validating XML against an XSD schema. The datatypes and their lexical forms are defined in XML Schema Part 2: Datatypes, and xs:any in the Structures specification. Check a value against an expression with the XPath tester.
When the error is in the schema, not the document
Every valid-looking document fails the same way. If all files from different senders produce the same message at the same element, the schema is wrong or has drifted from the format that is actually in use.
The schema does not compile. Errors such as "element declaration is referenced but not defined" or a failure to resolve an import are about the schema and are reported when it is loaded, with no document involved.
The rule belongs elsewhere. If the fix is to make the schema accept anything, the rule is probably not a shape rule at all. Move it to a Schematron assertion or to code.
The sender disagrees about the contract. Show them the schema and the message. If they argue the schema is wrong, settle it in the schema and version it (testing feed compatibility before a schema change), not in an email thread.


