NationalSecurityAgency/ghidra · warning · ElasticException

Elasticsearch database does not have callgraph information…

Error message

Elasticsearch database does not have callgraph information enabled

What it means

Thrown by ElasticDatabase.fillinChildren when asked to expand the children of a function but the database's DatabaseInformation.trackcallgraph flag is false. trackcallgraph is a per-database attribute fixed at initialization/ingest time; when false the index never stored callgraph edges, so child expansion is impossible. This guard sits inside the internal recursion path (distinct from the command-level check in fdbQueryChildren).

Solutions

  1. Inspect database.getInfo().trackcallgraph before invoking any callgraph-expanding query and disable that UI/code path when false.
  2. Re-create or re-initialize the Elasticsearch BSim database with trackcallgraph=true and re-ingest executables.
  3. If you only need similarity (not call edges), use a non-callgraph query path so fillinChildren is never reached.

Example fix

// before
fillinChildren(element, response.manage, funcmap);
// after
if (database.getInfo().trackcallgraph) {
    fillinChildren(element, response.manage, funcmap);
}
Defensive patterns

Strategy: validation

Validate before calling

DatabaseInformation info = database.getInfo();
if (!info.trackcallgraph) {
    // disable child-expansion UI/code path
    return;
}

Type guard

static boolean supportsCallgraph(FunctionDatabase db) {
    DatabaseInformation info = db.getInfo();
    return info != null && info.trackcallgraph;
}

Try / catch

if (!database.getInfo().trackcallgraph) {
    // skip callgraph expansion gracefully
} else {
    fillinChildren(element, manager, functionMap);
}

Prevention

When it happens

Trigger: Any code path that drives fillinChildren on a database created with trackcallgraph=false — typically a query that internally traverses callgraph edges (overview/nearest with child expansion) without first checking the capability.

Common situations: Database initialized with trackcallgraph=false (either explicitly or via an older initialize config) and then queried with a callgraph-dependent operation; mixing an old DB created before callgraph tracking against a newer client that assumes it.

Related errors


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

Appendix: source

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

		JsonObject source = (JsonObject) resp.get("_source");
		JsonArray childid = (JsonArray) source.get("childid");
		return childid;
	}

	/**
	 * Given a specific function, query for all of its child functions.
	 * Uses a RowKey->FunctionDescription map to cache functions and avoid
	 * querying for the same function multiple times
	 * @param funcRecord is the specified function
	 * @param manager is the container for new child FunctionDescriptions
	 * @param functionMap is the cache
	 * @throws ElasticException for communication problems with the server
	 * @throws LSHException for problems adding records to the container
	 */
	private void fillinChildren(FunctionDescription funcRecord, DescriptionManager manager,
			Map<RowKey, FunctionDescription> functionMap) throws ElasticException, LSHException {
		if (!info.trackcallgraph) {
			throw new ElasticException(
				"Elasticsearch database does not have callgraph information enabled");
		}
		JsonArray callids = queryCallgraphRows(funcRecord);
		if (callids == null) {
			return;		// field is not present, meaning children are not present
		}
		for (JsonElement callid : callids) {
			String funcId = callid.getAsString();
			RowKeyElastic eKey = RowKeyElastic.parseFunctionId(funcId);
			FunctionDescription fdesc = functionMap.get(eKey);
			if (fdesc == null) {
				fdesc = querySingleDescriptionId(manager, funcId);
				functionMap.put(eKey, fdesc);
			}
			manager.makeCallgraphLink(funcRecord, fdesc, 0);
		}
	}

View on GitHub (pinned to d5f144c24d)