NationalSecurityAgency/ghidra · error · IllegalArgumentException

Space must be a memory, register, or NO_ADDRESS space

Error message

Space must be a memory, register, or NO_ADDRESS space

What it means

Thrown by AbstractDBTraceSpaceBasedManager.getForSpace when the given AddressSpace is neither a memory space, a register space, nor the special Address.NO_ADDRESS space. Trace space-based managers (memory, registers, code units, etc.) only operate on these three categories. Passing a constant/unique/hash/custom address space is rejected to keep per-space storage meaningful.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/space/AbstractDBTraceSpaceBasedManager.java:142

		AddressFactory factory = trace.getBaseAddressFactory();
		List<TabledSpace> result = new ArrayList<>();
		for (DBTraceSpaceEntry ent : spaceStore.asMap().values()) {
			AddressSpace space = getSpaceByName(factory, ent.spaceName);
			if (space == null) {
				Msg.error(this, "Space " + ent.spaceName + " does not exist in trace (language=" +
					baseLanguage + ").");
				continue;
			}
			result.add(new TabledSpace(ent, space));
		}
		return result;
	}

	protected M getForSpace(AddressSpace space, boolean createIfAbsent) {
		trace.assertValidSpace(Objects.requireNonNull(space));
		if (!space.isMemorySpace() && !space.isRegisterSpace() &&
			space != Address.NO_ADDRESS.getAddressSpace()) {
			throw new IllegalArgumentException(
				"Space must be a memory, register, or NO_ADDRESS space");
		}
		if (!createIfAbsent) {
			try (LockHold hold = LockHold.lock(lock.readLock())) {
				return spaces.get(space);
			}
		}
		try (LockHold hold = LockHold.lock(lock.writeLock())) {
			return spaces.computeIfAbsent(space, s -> {
				// NOTE: Require caller to start transaction
				try {
					DBTraceSpaceEntry ent = spaceStore.create();
					ent.set(space.getName(), -1, 0);
					return createSpace(space, ent);
				}
				catch (VersionException e) {
					throw new AssertionError(e);
				}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Guard the call: if (!space.isMemorySpace() && !space.isRegisterSpace() && space != Address.NO_ADDRESS.getAddressSpace()) skip it.
  2. Use the correct manager for the address type (register addresses -> register manager).
  3. Resolve the physical/overlay space before calling getForSpace.

Example fix

// before
mgr.getForSpace(addr.getAddressSpace(), true);
// after
AddressSpace sp = addr.getAddressSpace();
if (sp.isMemorySpace() || sp.isRegisterSpace() ||
    sp == Address.NO_ADDRESS.getAddressSpace()) {
    mgr.getForSpace(sp, true);
}
Defensive patterns

Strategy: validation

Validate before calling

AddressSpace sp = ...;
if (!sp.isMemorySpace() && !sp.isRegisterSpace() &&
    sp != Address.NO_ADDRESS.getAddressSpace()) {
    return; // or route elsewhere
}
mgr.getForSpace(sp, createIfAbsent);

Type guard

static boolean isTraceSpace(AddressSpace sp) {
    return sp.isMemorySpace() || sp.isRegisterSpace()
        || sp == Address.NO_ADDRESS.getAddressSpace();
}

Prevention

When it happens

Trigger: Calling a space-scoped API with addrSpace == constantSpace, a unique space, or a user-defined non-memory address space. Passing the address space derived from a constant address into a memory/register manager.

Common situations: Tooling that iterates over all AddressSpaces from a language and forgets to skip constant/unique spaces; mis-routing a register address into a code path expecting memory.

Related errors


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