NationalSecurityAgency/ghidra · error · LSHException
Unknown tag: {el.getName()}
Error message
Unknown tag: {el.getName()} What it means
Thrown by QueryNearestVector.restoreXml while deserializing a <querynearestvector> BSim request. After manage/simthresh/signifthresh, the only optional child element accepted is <vectormax>; any other start element raises LSHException. Like QueryNearest, this is strict schema enforcement during XML parsing.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/protocol/QueryNearestVector.java:95
fwrite.append("<vectormax>").append(SpecXmlUtils.encodeSignedInteger(vectormax)).append("</vectormax>\n");
fwrite.append("</").append(name).append(">\n");
}
@Override
public void restoreXml(XmlPullParser parser, LSHVectorFactory vectorFactory) throws LSHException {
vectormax = 0; // Default
parser.start(name);
manage.restoreXml(parser, vectorFactory);
parser.start("simthresh");
thresh = Double.parseDouble(parser.end().getText());
parser.start("signifthresh");
signifthresh = Double.parseDouble(parser.end().getText());
while (parser.peek().isStart()) {
XmlElement el = parser.start();
if (el.getName().equals("vectormax"))
vectormax = SpecXmlUtils.decodeInt(parser.end().getText());
else
throw new LSHException("Unknown tag: "+el.getName());
}
parser.end();
}
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Use matching Ghidra/BSim versions on client and server.
- If you have a QueryNearest-style payload, send it as <querynearest>, not <querynearestvector>.
- Pre-validate that child elements of the body are only <vectormax> before calling restoreXml.
- Regenerate the XML from a QueryNearestVector object via saveXml rather than hand-authoring.
Example fix
// before QueryNearestVector q = new QueryNearestVector(); q.restoreXml(parser, vectorFactory); // unknown tag // after - regenerate from object instead of feeding alien XML QueryNearestVector q = new QueryNearestVector(); q.thresh = 0.7; q.signifthresh = 0.0; q.vectormax = 50; StringWriter sw = new StringWriter(); q.saveXml(sw); // parse sw.toString() back - guaranteed schema-valid
Defensive patterns
Strategy: validation
Validate before calling
// QueryNearestVector accepts only <vectormax> after the fixed children
Set<String> allowed = Set.of("vectormax");
// pre-walk body starts and verify each name is in `allowed` before restoreXml Type guard
static boolean isKnownQueryNearestVectorChild(String tag) {
return "vectormax".equals(tag);
} Try / catch
try {
q.restoreXml(parser, vectorFactory);
} catch (LSHException e) {
if (e.getMessage().startsWith("Unknown tag:")) {
// likely a QueryNearest payload fed to a vector query parser
throw new LSHException("Wrong query type or version: " + e.getMessage());
}
throw e;
} Prevention
- Do not feed QueryNearest XML into QueryNearestVector.restoreXml.
- Match client/server Ghidra versions.
- Regenerate XML via QueryNearestVector.saveXml instead of editing by hand.
When it happens
Trigger: Calling QueryNearestVector.restoreXml(parser, vectorFactory) where the XML body contains an element other than <vectormax>. Typically a version mismatch (a newer client serializes a tag like <categories> or <exefilter> that QueryNearestVector does not support) or corrupt/hand-edited XML.
Common situations: BSim client/server version skew. Confusing QueryNearest XML (which supports more tags) with QueryNearestVector XML. Manually authored request XML with extra elements.
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/cea9250fd9b868d8.
Report an issue: GitHub.