NationalSecurityAgency/ghidra · error · AddressTranslationException

The specified source address never had an external address p

Error message

The specified source address never had an external address pair added to the translator.

What it means

Thrown as AddressTranslationException by ExternalsAddressTranslator.getAddress when the supplied source address has no entry in the translator's internal addressMap. The class is explicitly one-to-one and requires every translatable source address to be registered first via setPair(destination, source). A lookup miss means the caller forgot (or failed) to register the pair before querying.

Source

Thrown at Ghidra/Features/Base/src/main/java/ghidra/app/merge/listing/ExternalsAddressTranslator.java:70

	}

	public void setPair(Address destinationAddress, Address sourceAddress) {
		// Should this actually do a clear first, instead of the check and possible remove?
		if (destinationAddress != null) {
			addressMap.put(sourceAddress, destinationAddress);
		}
		else {
			addressMap.remove(sourceAddress);
		}
	}

	@Override
	public Address getAddress(Address sourceAddress) {
		Address destinationAddress = addressMap.get(sourceAddress);
		if (destinationAddress != null) {
			return destinationAddress;
		}
		throw new AddressTranslationException(
			"The specified source address never had an external address pair added to the translator.");
	}

	@Override
	public boolean isOneForOneTranslator() {
		return true;
	}

	@Override
	public AddressSet getAddressSet(AddressSetView sourceAddressSet) {
		if (sourceAddressSet == null) {
			return null;
		}
		if (sourceAddressSet.getNumAddresses() > 1) {
			throw new AddressTranslationException(
				"An external address translator can only handle a single address at a time, if that.");
		}
		AddressSet destinationSet = new AddressSet();

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Before calling getAddress, ensure setPair(destination, source) has been invoked for every external source address you intend to translate.
  2. Prefer the higher-level ProgramMerge helpers that build the translator pairs for you rather than calling getAddress directly.
  3. Wrap the call in try/catch(AddressTranslationException) and fall back to SimpleDiffUtility.getCompatibleAddress for unmapped externals.
  4. If you iterate a set of source addresses, register the full set up front rather than ad hoc.

Example fix

// before
Address dest = translator.getAddress(sourceAddr); // throws if not registered

// after — register first, or fall back
translator.setPair(mappedDest, sourceAddr);
Address dest = translator.getAddress(sourceAddr);
Defensive patterns

Strategy: validation

Validate before calling

// register the pair before lookup
translator.setPair(destinationAddress, sourceAddress);
// optionally probe without throwing
boolean known = /* expose addressMap.containsKey via a wrapper */;

Type guard

// no direct key check on the interface; guard by ensuring setPair was called
assert translator.getAddress(dest) != null : "pair not registered";

Try / catch

try {
    Address d = translator.getAddress(source);
} catch (AddressTranslationException e) {
    d = SimpleDiffUtility.getCompatibleAddress(srcProgram, source, destProgram);
}

Prevention

When it happens

Trigger: Calling getAddress(sourceAddress) on an ExternalsAddressTranslator instance without first calling setPair(destination, source) for that exact source address; passing a source address from a different program or address space than the one used at registration time.

Common situations: Merging external functions/labels across two programs where the caller pre-populated pairs for some external locations but not all; refactoring a ProgramMerge flow and dropping the setPair loop; using a source address computed via a different DiffUtility path than the one used to build the map.

Related errors


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