NationalSecurityAgency/ghidra · warning · LSHException

Could not find executable

Error message

Could not find executable

What it means

Thrown by ExecutableComparison.lookupExecutable when a QueryName query succeeds (non-null response) but the result set does not contain exactly one executable (response.manage.numExecutables() != 1). Typically this means zero executables matched the given MD5 — the executable does not exist in the database.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/ExecutableComparison.java:172

	 * @param md5 is the md5 String
	 * @return the corresponding ExecutableRecord
	 * @throws LSHException if there are problems accessing the database
	 *    or the executable doesn't exist
	 */
	private ExecutableRecord lookupExecutable(String md5) throws LSHException {
		QueryName query = new QueryName();
		query.spec = new ExeSpecifier();
		query.spec.exemd5 = md5;
		query.maxfunc = 1;
		query.fillinCallgraph = false;
		query.fillinCategories = false;
		query.fillinSigs = false;
		ResponseName response = query.execute(database);
		if (response == null) {
			throw new LSHException(database.getLastError().message);
		}
		if (response.manage.numExecutables() != 1) {
			throw new LSHException("Could not find executable");
		}
		return response.manage.getExecutableRecordSet().first();
	}

	/**
	 * Query for all the vector ids associated with a specific executable.
	 * Store them in the vectorMap
	 * @param exeSpec indicates the specific executable
	 * @param histogram is non-null, provide a histogram of the vector ids
	 */
	private void pullVectorsForExe(ExeSpecifier exeSpec, Map<Long, Count> histogram) {
		QueryName queryName = new QueryName();
		queryName.spec = exeSpec;
		// TODO: Need to make more of an effort to collect all vectors for large executables.
		// But, this requires a change to the QueryName API to allow a window to be specified
		queryName.maxfunc = 100000;
		queryName.fillinCallgraph = false;
		queryName.fillinCategories = false;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Confirm the MD5 exists in the target database (query executable list or check ingestion).
  2. Verify the MD5 string is correct and formatted as expected.
  3. Ensure ingestion has completed before querying.
  4. Handle the 'not found' case gracefully in the caller.

Example fix

// before
ExecutableRecord rec = cmp.lookupExecutable(md5); // throws if absent
// after
ResponseName resp = query.execute(database);
if (resp == null || resp.manage.numExecutables() != 1) {
    // handle not-found: skip or report
    return null;
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check existence:
QueryExeInfo check = new QueryExeInfo(0, md5, null, null, null, null, false);
ResponseExe r = check.execute(database);
if (r == null || r.records.isEmpty()) {
    // MD5 not in DB; skip lookup
}

Try / catch

catch (LSHException e) { if (e.getMessage().contains("Could not find executable")) { /* handle missing MD5 gracefully */ } }

Prevention

When it happens

Trigger: Looking up an MD5 that is not present in the BSim database; MD5 from a different database; executable was never ingested or was deleted; incorrect/typo MD5 string.

Common situations: Cross-referencing an MD5 against the wrong database; querying before ingestion completes; stale MD5 references; case-sensitivity or formatting mismatch in the MD5 string.

Related errors


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