NationalSecurityAgency/ghidra · error · LSHException

Could not (uniquely) match executable

Error message

Could not (uniquely) match executable

What it means

Thrown by ElasticDatabase.fdbQueryChildren when findSingleExecutable returns null for the ExeSpecifier built from query.md5sum/name_exec/arch/name_compiler. findSingleExecutable returns null when zero OR more than one executable matches the specifier, hence '(uniquely)' in the message — the command requires exactly one match to resolve functions against.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java:3550

	 * @throws LSHException for problems adding records to the response
	 * @throws ElasticException for communication problems with the server
	 */
	private void fdbQueryChildren(QueryChildren query) throws LSHException, ElasticException {
		if (!info.trackcallgraph) {
			throw new LSHException("Database does not track callgraph");
		}
		ResponseChildren response = query.childrenresponse;
		ExecutableRecord exe = null;

		ExeSpecifier exeSpec = new ExeSpecifier();
		exeSpec.exemd5 = query.md5sum;
		exeSpec.exename = query.name_exec;
		exeSpec.arch = query.arch;
		exeSpec.execompname = query.name_compiler;

		exe = findSingleExecutable(exeSpec, response.manage);
		if (exe == null) {
			throw new LSHException("Could not (uniquely) match executable");
		}
		for (FunctionEntry entry : query.functionKeys) {
			FunctionDescription func =
				queryByNameAddress(response.manage, exe, entry.funcName, entry.address, true);
			if (func == null) {
				throw new LSHException("Could not find function: " + entry.funcName);
			}
			response.correspond.add(func);
		}

		TreeMap<RowKey, FunctionDescription> funcmap = new TreeMap<>();
		response.manage.generateFunctionIdMap(funcmap);
		for (FunctionDescription element : response.correspond) {
			fillinChildren(element, response.manage, funcmap);
		}
	}

	/**

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Provide all four identifying fields (md5, name, arch, compiler) to make the match unique; md5 alone is usually sufficient.
  2. If unsure which executable matches, first run a QueryName/exe-info query to enumerate candidates, then issue QueryChildren with the exact md5.
  3. Deduplicate or reconcile executables in the database if a legitimate single binary appears twice.

Example fix

// before
query.md5sum = md5;            // may be null/blank
query.name_exec = name;
// after
query.md5sum = exactMd5;        // full 32-hex md5 uniquely identifies
query.name_exec = name;
query.arch = program.getLanguageID().toString();
Defensive patterns

Strategy: validation

Validate before calling

// provide all fields; md5 makes the match unique
ExeSpecifier spec = new ExeSpecifier();
spec.exemd5 = exactMd5;          // 32 hex chars
spec.exename = name;
spec.arch = arch;
spec.execompname = compiler;
// verify a unique match via QueryName before QueryChildren if unsure

Type guard

static boolean isFullySpecified(ExeSpecifier s) {
    return s.exemd5 != null && s.exemd5.matches("[0-9a-fA-F]{32}");
}

Try / catch

try {
    fdbQueryChildren(query);
} catch (LSHException e) {
    if (e.getMessage().startsWith("Could not (uniquely) match executable")) {
        // enumerate candidates and re-prompt the user to disambiguate
    } else throw e;
}

Prevention

When it happens

Trigger: Submitting QueryChildren with an ExeSpecifier that matches no executable (wrong md5/name/arch/compiler) or matches multiple executables (ambiguous partial fields, e.g. same name+arch across two md5s).

Common situations: Typo or stale md5 in the query; leaving arch/compiler fields blank so several executables collide; querying after executables were merged/duplicated in the DB.

Related errors


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