apache/hadoop · error · InvalidXmlException

expected an <OPCODE> tag

Error message

expected an <OPCODE> tag

What it means

Inside a <RECORD>, the state machine enters EXPECT_OPCODE and the first child element must be <OPCODE> (the numeric edit opcode). Any other tag first throws InvalidXmlException('expected an <OPCODE> tag'). Records are rigidly ordered: OPCODE then DATA.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/OfflineEditsXmlLoader.java:159

      }
      state = ParseState.EXPECT_VERSION;
      break;
    case EXPECT_VERSION:
      if (!name.equals("EDITS_VERSION")) {
        throw new InvalidXmlException("you must put " +
            "<EDITS_VERSION> at the top of the XML file! " +
            "Got tag " + name + " instead");
      }
      break;
    case EXPECT_RECORD:
      if (!name.equals("RECORD")) {
        throw new InvalidXmlException("expected a <RECORD> tag");
      }
      state = ParseState.EXPECT_OPCODE;
      break;
    case EXPECT_OPCODE:
      if (!name.equals("OPCODE")) {
        throw new InvalidXmlException("expected an <OPCODE> tag");
      }
      break;
    case EXPECT_DATA:
      if (!name.equals("DATA")) {
        throw new InvalidXmlException("expected a <DATA> tag");
      }
      stanza = new Stanza();
      state = ParseState.HANDLE_DATA;
      break;
    case HANDLE_DATA:
      Stanza parent = stanza;
      Stanza child = new Stanza();
      stanzaStack.push(parent);
      stanza = child;
      parent.addChild(name, child);
      break;
    case EXPECT_END:
      throw new InvalidXmlException("not expecting anything after </EDITS>");

View on GitHub (pinned to 2add963021)

Solutions

  1. Put <OPCODE>value</OPCODE> immediately inside <RECORD>, before <DATA>.
  2. Disable child reordering in any XSLT/serializer used to produce the file.
  3. Regenerate from the binary edits via oev to guarantee opcode/data ordering.

Example fix

<!-- before -->
<RECORD><DATA><TXID>1</TXID></DATA><OPCODE>9</OPCODE></RECORD>

<!-- after -->
<RECORD><OPCODE>9</OPCODE><DATA><TXID>1</TXID></DATA></RECORD>
Defensive patterns

Strategy: validation

Validate before calling

// Inside each RECORD, first child must be OPCODE
try (XMLStreamReader r = XMLInputFactory.newFactory()
        .createXMLStreamReader(new FileInputStream(file))) {
  while (r.hasNext()) {
    int ev = r.next();
    if (ev == XMLStreamConstants.START_ELEMENT
        && "RECORD".equals(r.getLocalName())) {
      r.nextTag();
      if (!"OPCODE".equals(r.getLocalName())) {
        throw new IOException("<RECORD> must start with <OPCODE>, found <"
            + r.getLocalName() + ">");
      }
    }
  }
}

Try / catch

try {
  loader.loadEdits();
} catch (InvalidXmlException e) {
  if (e.getMessage().contains("<OPCODE>")) {
    throw new IOException("Record children are order-sensitive: "
        + "<OPCODE> must precede <DATA>. " + e.getMessage(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: A <RECORD> whose first child is <DATA> (order swapped or OPCODE deleted), or an extra wrapper element inserted before the opcode during manual editing or transform.

Common situations: Hand-crafted fixtures with reversed children; XML transformers reordering children alphabetically (DATA before OPCODE); merging records and losing the opcode element.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/c90dbf316b812bd5. Report an issue: GitHub.