NationalSecurityAgency/ghidra · error · LSHException
Unknown tag: {el.getName()}
Error message
Unknown tag: {el.getName()} What it means
Thrown by QueryNearest.restoreXml while deserializing a <querynearest> BSim request. After parsing manage, simthresh, signifthresh and max, the parser loops over remaining start elements and only accepts <vectormax>, <categories>, and <exefilter>; any other tag name raises LSHException. This is strict schema validation so that malformed or version-mismatched XML fails fast instead of being silently dropped.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/protocol/QueryNearest.java:140
signifthresh = Double.parseDouble(parser.end().getText());
parser.start("max");
max = SpecXmlUtils.decodeInt(parser.end().getText());
while (parser.peek().isStart()) {
XmlElement el = parser.peek();
if (el.getName().equals("vectormax")) {
parser.start();
vectormax = SpecXmlUtils.decodeInt(parser.end().getText());
}
else 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
throw new LSHException("Unknown tag: "+el.getName());
}
parser.end();
}
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Ensure the client and server run the same Ghidra/BSim version so the serialized XML schema matches the parser.
- Validate the XML against the expected tag set (vectormax, categories, exefilter) before calling restoreXml.
- Inspect the offending tag name in the exception message to identify which extra field was serialized and remove or downgrade it.
- If intercepting traffic, regenerate the request with a QueryNearest object via saveXml instead of hand-authoring XML.
Example fix
// before
QueryNearest q = new QueryNearest();
q.restoreXml(parser, vectorFactory); // throws on unknown tag
// after
Set<String> allowed = Set.of("vectormax", "categories", "exefilter", "simthresh", "signifthresh", "max");
// pre-scan: ensure remaining child tags are within the allowed set
QueryNearest q = new QueryNearest();
try {
q.restoreXml(parser, vectorFactory);
} catch (LSHException e) {
throw new LSHException("Schema mismatch - check BSim client/server version: " + e.getMessage());
} Defensive patterns
Strategy: validation
Validate before calling
Set<String> allowed = Set.of("vectormax", "categories", "exefilter");
// pre-walk child starts of the querynearest element and assert names are in `allowed`
// before calling restoreXml Type guard
static boolean isKnownQueryNearestChild(String tag) {
return Set.of("vectormax", "categories", "exefilter").contains(tag);
} Try / catch
try {
q.restoreXml(parser, vectorFactory);
} catch (LSHException e) {
if (e.getMessage().startsWith("Unknown tag:")) {
throw new LSHException(
"BSim schema mismatch (client/server version?): " + e.getMessage());
}
throw e;
} Prevention
- Keep BSim client and server on the same Ghidra release.
- Prefer building requests via the QueryNearest object API and saveXml over hand-authoring XML.
- Version-stamp your serialized requests so a mismatch can be detected before parsing.
When it happens
Trigger: Calling QueryNearest.restoreXml(parser, vectorFactory) on XML that contains an element other than vectormax/categories/exefilter after <max>. Happens when the client and server disagree on the request schema (e.g. newer client serializes a tag the older parser doesn't know), or when hand-edited/corrupt XML is fed in.
Common situations: Version skew between a BSim client and server (a field added in a newer Ghidra release). Feeding a query XML document produced by a different BSim dialect. Manually constructing XML and misspelling a tag.
Related errors
- Unknown tag: {el.getName()}
- Unknown tag: {el.getName()}
- Bad category tag
- Old XML layout is no longer supported
- XML layout for newer version of BSIM
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/624b4eb9cb088111.
Report an issue: GitHub.