cvc-complex-type.2.4.a: Invalid content was found starting with element

Java found an element where the schema expects a different one: out of order, misspelt, or in another namespace.

The message, as Java reports it
cvc-complex-type.2.4.a: Invalid content was found starting with element 'qty'. One of '{id}' is expected.

Why it happens

  • Elements in a different order than the schema's xs:sequence: the order matters, and the message names the element that came too early.
  • A namespace mismatch, the most common cause when the names look identical. Xerces writes a namespaced name as "urn:example":id inside the braces: if the expected names carry a namespace and the element in the document has none (a missing xmlns="…"), or the other way round, they don't match.
  • A misspelt name, a different letter case, or an element the schema doesn't allow at that point at all.

How to fix it

Read the list in braces: it is everything the schema would accept at that point. If one of them is in the document further down, move it up; if it is missing, add it; if the names look the same, compare their namespaces. With JAXB, check the namespace of @XmlRootElement and @XmlElement and the elementFormDefault in package-info.java.

Java's schema validation (javax.xml.validation.Validator, and JAXB or Spring on top of it) throws at the first error unless you set an ErrorHandler whose error() records the SAXParseException and carries on; each one has getLineNumber() and getColumnNumber(). A well-formedness error ends parsing whatever the handler does.

The same problem in xmlvalid

xmlvalid validates with libxml2, which reports it as This element is not expected. It checks the whole document in your browser and lists every schema error with its line and column, not only the first.

Element 'qty': This element is not expected. Expected is ( id ).

Example

Validated against order.xsd, below. In order.xsd, id must come before qty.

Reports the error
<order currency="EUR">
  <qty>1</qty>
  <id>A-1</id>
</order>
Fixed
<order currency="EUR">
  <id>A-1</id>
  <qty>1</qty>
</order>
order.xsd
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="order">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="id" type="xs:string"/>
        <xs:element name="qty" type="xs:int"/>
        <xs:element name="status" type="Status" minOccurs="0"/>
        <xs:element name="code" type="Code" minOccurs="0"/>
        <xs:element name="note" type="Short" minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="currency" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="Status">
    <xs:restriction base="xs:string">
      <xs:enumeration value="open"/>
      <xs:enumeration value="paid"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="Code">
    <xs:restriction base="xs:string">
      <xs:pattern value="[A-Z]{3}-[0-9]{4}"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="Short">
    <xs:restriction base="xs:string">
      <xs:maxLength value="10"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>