NationalSecurityAgency/ghidra · error · LSHException

Self-score not recorded for {md5}

Error message

Self-score not recorded for {md5}

What it means

Thrown by FileScoreCaching.getSelfScore() when the cache loads successfully (or the file does not exist, leaving cacheMap null) but the requested md5 is not present in the cache map. This means the executable's self-significance score was never committed, or no cache file exists at all.

Source

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

		}
		reader.close();
	}

	@Override
	public float getSelfScore(String md5) throws LSHException {
		try {
			loadCache();
		}
		catch (IOException e) {
			throw new LSHException("Could not recover cached scores: " + e.getMessage());
		}
		if (cacheMap != null) {
			Float val = cacheMap.get(md5);
			if (val != null) {
				return val.floatValue();
			}
		}
		throw new LSHException("Self-score not recorded for " + md5);
	}

	@Override
	public void commitSelfScore(String md5, float score) throws LSHException {
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(storageFile, true));
			if (cacheMap == null) {
				writer.write(Double.toString(simThreshold));
				writer.newLine();
				writer.write(Double.toString(sigThreshold));
				writer.newLine();
				cacheMap = new TreeMap<String, Float>();
			}
			cacheMap.put(md5, score);
			writer.write(md5);
			writer.append(' ');
			writer.write(Float.toString(score));
			writer.newLine();

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure the executable's self-score has been committed via commitSelfScore(md5, score) before querying it.
  2. Use prefetchScores(exeSet, missing) to batch-load scores and identify which executables are missing in one call.
  3. Verify the md5 string is the correct 32-character hash of the target executable.

Example fix

// before
float score = cache.getSelfScore(md5); // throws if not yet committed

// after — check and commit if missing
List<ExecutableRecord> missing = new ArrayList<>();
cache.prefetchScores(exeSet, missing);
if (missing.contains(exeRec)) {
    cache.commitSelfScore(exeRec.getMd5(), computedScore);
}
float score = cache.getSelfScore(md5);
Defensive patterns

Strategy: validation

Validate before calling

// Check if the score exists before fetching
List<ExecutableRecord> missing = new ArrayList<>();
cache.prefetchScores(exeSet, missing);
boolean hasScore = !missing.contains(exeRec);

Try / catch

try {
    return cache.getSelfScore(md5);
} catch (LSHException e) {
    if (e.getMessage().startsWith("Self-score not recorded")) {
        // compute and commit the score first
        cache.commitSelfScore(md5, computedScore);
        return computedScore;
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getSelfScore(md5) for an executable whose self-score has not yet been computed and committed. Also thrown when the cache file does not exist (cacheMap stays null after loadCache returns early), making every lookup fail.

Common situations: Querying an executable that was never ingested/scored against this database. Using a fresh (non-existent) cache file before any commitSelfScore has been called. An md5 mismatch between the score key and the executable record.

Related errors


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