NationalSecurityAgency/ghidra · error · LSHException

Unknown tag: {el.getName()}

Error message

Unknown tag: {el.getName()}

What it means

Thrown by QueryVectorMatch.restoreXml while deserializing a <queryvectormatch> BSim request. After <max>, only <categories>, <exefilter>, and <id> start elements are accepted; anything else raises LSHException. Strict schema validation for the vector-id query protocol.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/protocol/QueryVectorMatch.java:100

		parser.start("max");
		max = SpecXmlUtils.decodeInt(parser.end().getText());
		while (parser.peek().isStart()) {
			XmlElement el = parser.peek();
			if (el.getName().equals("categories")) {
				parser.start();
				fillinCategories = SpecXmlUtils.decodeBoolean(parser.end().getText());
			}
			else if (el.getName().equals("exefilter")) {
				bsimFilter = new BSimFilter();
				bsimFilter.restoreXml(parser);
			}
			else if (el.getName().equals("id")) {
				parser.start();
				long val = SpecXmlUtils.decodeLong(parser.end().getText());
				vectorIds.add(val);
			}
			else {
				throw new LSHException("Unknown tag: " + el.getName());
			}

		}
		parser.end();
	}

}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Align client and server to the same Ghidra/BSim version.
  2. Ensure the payload was produced by QueryVectorMatch.saveXml, not QueryNearest.saveXml.
  3. Pre-scan child tags and reject any outside {categories, exefilter, id}.
  4. Use the QueryVectorMatch object API (set vectorIds, bsimFilter, etc.) and let saveXml generate canonical XML.

Example fix

// before
QueryVectorMatch q = new QueryVectorMatch();
q.restoreXml(parser, vectorFactory); // unknown tag

// after
QueryVectorMatch q = new QueryVectorMatch();
q.vectorIds.add(0x1234L);
q.fillinCategories = false;
StringWriter sw = new StringWriter();
q.saveXml(sw); // emit canonical XML, then parse it back
Defensive patterns

Strategy: validation

Validate before calling

Set<String> allowed = Set.of("categories", "exefilter", "id");
// after <max>, walk child starts and confirm names are within `allowed`

Type guard

static boolean isKnownQueryVectorMatchChild(String tag) {
    return Set.of("categories", "exefilter", "id").contains(tag);
}

Try / catch

try {
    q.restoreXml(parser, vectorFactory);
} catch (LSHException e) {
    if (e.getMessage().startsWith("Unknown tag:")) {
        throw new LSHException("Schema/version mismatch: " + e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling QueryVectorMatch.restoreXml(parser, vectorFactory) on XML containing a child element other than categories/exefilter/id after <max>. Caused by version mismatch, hand-edited XML, or feeding a QueryNearest-style payload to the vector-match parser.

Common situations: BSim client/server version skew. Mixing QueryNearest and QueryVectorMatch XML payloads. Misspelled tag names in hand-authored XML.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/b066d59987f42439. Report an issue: GitHub.