NationalSecurityAgency/ghidra · error · IllegalArgumentException

Length must match the register

Error message

Length must match the register

What it means

Thrown by DBTraceObjectRegister.setValue() when the byte array value's length does not match the register's expected byte length. The method computes length = getByteLength(lifespan.lmin()) and checks length != 0 (meaning the register size is known) and value.length != length. An IllegalArgumentException (unchecked) enforces that register writes must use exactly the register's native width.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceObjectRegister.java:68

	}

	@Override
	public String getName() {
		KeyPath path = object.getCanonicalPath();
		return KeyPath.parseIfIndex(path.key());
	}

	@Override
	public int getBitLength(long snap) {
		return TraceObjectInterfaceUtils.getValue(object, snap, TraceRegister.KEY_BITLENGTH,
			Integer.class, 0);
	}

	@Override
	public void setValue(Lifespan lifespan, byte[] value) {
		int length = getByteLength(lifespan.lmin());
		if (length != 0 && value.length != length) {
			throw new IllegalArgumentException("Length must match the register");
		}
		object.setValue(lifespan, TraceRegister.KEY_VALUE, value);
	}

	@Override
	public byte[] getValue(long snap) {
		TraceObjectValue ov = object.getValue(snap, TraceRegister.KEY_VALUE);
		if (ov == null) {
			return null;
		}
		Object val = ov.getValue();
		if (val instanceof byte[] arr) {
			// TODO: Should I correct mismatched size?
			return arr;
		}
		if (val instanceof String str) {
			// Always base 16. Model API says byte array for register value is big endian.
			BigInteger bigVal = new BigInteger(str, 16);

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Pad or truncate the byte array to match getByteLength(snap) before calling setValue().
  2. Use Utils.bigIntegerToBytes(BigInteger.valueOf(val), reg.getByteLength(snap), true) to generate a correctly-sized byte array.
  3. Verify the register's bit length via getBitLength(snap) and compute expected byte length before writing.

Example fix

// before
reg.setValue(lifespan, rawBytes); // rawBytes.length != expected

// after
int expectedLen = reg.getByteLength(lifespan.lmin());
byte[] fixed = Arrays.copyOf(rawBytes, expectedLen);
reg.setValue(lifespan, fixed);
Defensive patterns

Strategy: validation

Validate before calling

// Verify byte length matches before setting register value
int expectedLen = reg.getByteLength(lifespan.lmin());
if (expectedLen != 0 && value.length != expectedLen) {
    value = Arrays.copyOf(value, expectedLen); // pad or truncate
}
reg.setValue(lifespan, value);

Prevention

When it happens

Trigger: Calling setValue(lifespan, value) on a DBTraceObjectRegister where value.length differs from the register's byte length at the given snap. For example, writing a 4-byte array to an 8-byte register, or a 2-byte array to a 1-byte register. The check is skipped only when getByteLength returns 0 (register size unknown at that snap).

Common situations: Recording register values from a target whose register width differs from the trace's language definition. Endianness or width conversion errors when preparing register values. Using a register value from one architecture in a trace configured for another.

Related errors


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