apache/maven · error · XMLStreamException
Expected root element '${rootTag}' but found '{}'
Error message
Expected root element '${rootTag}' but found '{}' What it means
The classic modello STAX reader template (reader.vm, without the location-tracking/context features of reader-stax.vm) emits the same strict-mode root guard: in read(XMLStreamReader, strict), the first START_ELEMENT's local name must equal the model's root tag, otherwise the parse aborts with the local name that was found (parser.getLocalName() in this variant). It protects a model-specific reader from the wrong document type.
Source
Thrown at src/mdo/reader.vm:442
/**
* Method read.
*
* @param parser a parser object.
* @param strict a strict object.
* @throws IOException IOException if any.
* @throws XMLStreamException XMLStreamException if
* any.
* @return ${root.name}
*/
public ${root.name} read(XMLStreamReader parser, boolean strict) throws IOException, XMLStreamException {
$rootUcapName $rootLcapName = null;
int eventType = parser.getEventType();
boolean parsed = false;
while (eventType != XMLStreamReader.END_DOCUMENT) {
if (eventType == XMLStreamReader.START_ELEMENT) {
if (strict && ! "${rootTag}".equals(parser.getLocalName())) {
throw new XMLStreamException("Expected root element '${rootTag}' but found '" + parser.getLocalName() + "'", parser.getLocation(), null);
} else if (parsed) {
// fallback, already expected a XMLStreamException due to invalid XML
throw new XMLStreamException("Duplicated tag: '${rootTag}'", parser.getLocation(), null);
}
$rootLcapName = parse${rootUcapName}(parser, strict);
parsed = true;
}
eventType = parser.next();
}
if (parsed) {
return $rootLcapName;
}
throw new XMLStreamException("Expected root element '${rootTag}' but found no element at all: invalid XML document", parser.getLocation(), null);
} //-- ${root.name} read(XMLStreamReader, boolean)
#foreach ( $class in $model.allClasses )
#if ( $class.name != "InputSource" && $class.name != "InputLocation" )
#set ( $classUcapName = $Helper.capitalise( $class.name ) )View on GitHub (pinned to e4093d4e12)
Solutions
- Confirm the document type and root element match this reader's model before parsing.
- Use the reader generated for the document at hand (pom vs settings vs metadata).
- Peek the root local name and dispatch to the right reader.
- If lenient reading is acceptable, call read(parser, false) to skip the root-name check.
Example fix
// before
Model model = new MavenXpp3Reader().read(in, true); // in held settings.xml
// after
byte[] bytes = in.readAllBytes();
String root = peekRootLocalName(new ByteArrayInputStream(bytes));
if (!"project".equals(root)) {
throw new IllegalArgumentException("Not a pom document, root element: " + root);
}
Model model = new MavenXpp3Reader().read(new ByteArrayInputStream(bytes), true); Defensive patterns
Strategy: validation
Validate before calling
byte[] bytes = in.readAllBytes();
XMLInputFactory f = XMLInputFactory.newFactory();
f.setProperty(XMLInputFactory.SUPPORT_DTD, false);
XMLStreamReader peek = f.createXMLStreamReader(new ByteArrayInputStream(bytes));
String root = null;
while (peek.hasNext()) {
if (peek.next() == XMLStreamReader.START_ELEMENT) { root = peek.getLocalName(); break; }
}
peek.close();
if (!"project".equals(root)) {
throw new IllegalArgumentException("Not a pom document, root element: " + root);
} Type guard
static boolean isRootElementMismatch(XMLStreamException e) {
return e.getMessage() != null && e.getMessage().startsWith("Expected root element");
} Try / catch
try {
Model model = reader.read(parser, true);
} catch (XMLStreamException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Expected root element")) {
// wrong document type for this reader; route elsewhere
}
throw e;
} Prevention
- Dispatch documents to readers by root element name.
- Always peek the root before a strict read.
- Keep reader version and document vocabulary in sync.
When it happens
Trigger: read(parser, true) or read(InputStream, true) on XML whose root element local name differs from the expected root tag: settings.xml fed to a POM reader, an XML fragment like <dependency>, or correct vocabulary nested at the wrong level.
Common situations: Mixed XML types routed through one parser; readers generated from a different model version; POM snippets copy-pasted without the <project> wrapper; the wrong file variable passed to read().
Related errors
- Expected root element '${rootTag}' but found '{}'
- Duplicated tag: '${rootTag}'
- Duplicated tag: '{}'
- Duplicated tag: '${rootTag}'
- Duplicated tag: '{}'
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/d7953299deb2b499.
Report an issue: GitHub.