NationalSecurityAgency/ghidra · error · LSHException
ExeSpecifier must provide either md5 or name
Error message
ExeSpecifier must provide either md5 or name
What it means
Thrown as LSHException (not ElasticException) by findSingleExecutable when an ExeSpecifier has neither an md5 (exemd5 null/empty) nor a name (exename empty). It is a caller-contract violation: the lookup needs at least one identifier to proceed. ExeSpecifier defaults all fields to empty strings, so an untouched specifier triggers it.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java:426
* Query for a single executable given uniquely specifying information (ExeSpecifier).
* The exe document is retrieved from the database and parsed into an ExecutableRecord object.
* @param specifier is the uniquely specifying info about the executable
* @param manager is container for the final ExecutableRecord
* @return the matching ExecutableRecord or null if none is found
* @throws LSHException if there are problems adding the queried record to the container
* @throws ElasticException for communication problems with the server
*/
private ExecutableRecord findSingleExecutable(ExeSpecifier specifier,
DescriptionManager manager) throws LSHException, ElasticException {
if (specifier.exemd5 != null && specifier.exemd5.length() != 0) {
JsonObject row = queryMd5ExeMatch(specifier.exemd5);
if (row == null) {
return null;
}
return makeExecutableRecord(manager, row);
}
if (StringUtils.isEmpty(specifier.exename)) {
throw new LSHException("ExeSpecifier must provide either md5 or name");
}
return querySingleExecutable(manager, specifier.exename, specifier.arch,
specifier.execompname);
}
/**
* Query for a single executable given uniquely specifying information (ExeSpecifier).
* A cache map is checked first for a previously recovered ExecutableRecord object.
* If not in the cache, the database is searched. If the executable is found, the ExecutableRecord
* is parsed from the database document, put into the cache, and returned to the user.
* @param specifier is the uniquely specifying info about the executable
* @param manager is container for the final ExecutableRecord
* @param nameMap is the cache of previously recovered records
* @return the matching ExecutableRecord or null if none is found
* @throws LSHException if there are problems adding the queried record to the container
* @throws ElasticException for communication problems with the server
*/
private ExecutableRecord findSingleExeWithMap(ExeSpecifier specifier,View on GitHub (pinned to d5f144c24d)
Solutions
- Before calling, ensure the ExeSpecifier has a non-empty exemd5 OR a non-empty exename; prefer md5 when available.
- If the specifier is built from a query object, validate query.md5sum / query.name_exec upstream and reject blank values with a clear error.
- When restoring from XML, treat a missing <md5> and missing/blank <name> as an invalid request.
Example fix
// before
ExeSpecifier spec = new ExeSpecifier();
ExecutableRecord r = db.findSingleExecutable(spec, mgr); // throws LSHException
// after
ExeSpecifier spec = new ExeSpecifier();
spec.exemd5 = md5 != null ? md5 : "";
spec.exename = name != null ? name : "";
if (spec.exemd5.isEmpty() && spec.exename.isEmpty()) {
throw new IllegalArgumentException("exe lookup needs an md5 or a name");
}
ExecutableRecord r = db.findSingleExecutable(spec, mgr); Defensive patterns
Strategy: validation
Validate before calling
public static ExeSpecifier requireIdentifier(ExeSpecifier s) {
boolean hasMd5 = s.exemd5 != null && !s.exemd5.isEmpty();
boolean hasName = s.exename != null && !s.exename.isEmpty();
if (!hasMd5 && !hasName)
throw new IllegalArgumentException("ExeSpecifier needs a non-empty md5 or name");
return s;
} Type guard
public static boolean hasIdentifier(ExeSpecifier s) {
return s != null && ((s.exemd5 != null && !s.exemd5.isEmpty()) || (s.exename != null && !s.exename.isEmpty()));
} Try / catch
try {
return db.findSingleExecutable(spec, mgr);
} catch (LSHException e) {
if (e.getMessage().equals("ExeSpecifier must provide either md5 or name"))
throw new IllegalArgumentException("Caller must set exe md5 or name", e);
throw e;
} Prevention
- ExeSpecifier defaults every field to empty string; never pass a freshly-constructed one unmodified.
- When deserializing <exe> XML, reject entries missing both <md5> and <name>.
- Prefer the md5 identifier when available for unambiguous lookups.
When it happens
Trigger: Calling findSingleExecutable (directly or via findSingleExeWithMap / the public query path) with an ExeSpecifier whose exemd5 is empty AND exename is empty. Arises from deserializing an <exe> XML block missing both <md5> and <name>, or building a specifier from a query whose md5sum and name_exec were both blank (see ElasticDatabase ~line 3543-3546).
Common situations: A BSim query request with no executable identifier filled in; malformed client XML missing the md5/name elements; programmatic specifier built but fields never assigned because the upstream md5/name were null.
Related errors
- Must specify "md5=" or "name="
- Executable
- Expecting privilege option (admin or user)
- host required
- Non-empty dbName required
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/c2b50fcfea4fad30.
Report an issue: GitHub.