NationalSecurityAgency/ghidra · error · RegisterValueException
Invalid register value {s}. Must be hex digits only.
Error message
Invalid register value {s}. Must be hex digits only. What it means
Thrown by RegisterValueConverter.convertValueToBigInteger when a register value stored as a String cannot be parsed as hexadecimal by new BigInteger(s, 16). String register values are expected to be hex-digit-only (with optional sign). Non-hex characters (G-Z, 'x' prefixes, spaces, decimal points) trigger this RegisterValueException.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/memory/RegisterValueConverter.java:41
public class RegisterValueConverter {
private final TraceObjectValue registerValue;
private BigInteger value;
private int bitLength = -1;
private byte[] be;
private byte[] le;
public RegisterValueConverter(TraceObjectValue registerValue) {
this.registerValue = registerValue;
}
public static BigInteger convertValueToBigInteger(Object val) throws RegisterValueException {
if (val instanceof String s) {
try {
return new BigInteger(s, 16);
}
catch (NumberFormatException e) {
throw new RegisterValueException(
"Invalid register value " + s + ". Must be hex digits only.");
}
}
else if (val instanceof byte[] arr) {
// NOTE: Reg object values are always big endian
return new BigInteger(1, arr);
}
else if (val instanceof Byte b) {
return BigInteger.valueOf(b);
}
else if (val instanceof Short s) {
return BigInteger.valueOf(s);
}
else if (val instanceof Integer i) {
return BigInteger.valueOf(i);
}
else if (val instanceof Long l) {
return BigInteger.valueOf(l);View on GitHub (pinned to d5f144c24d)
Solutions
- Normalize the stored value to bare hex digits before it reaches the converter (strip '0x', convert decimal->hex).
- If the value format is wrong, fix the target connector/emulator that writes register values.
- Catch RegisterValueException at the read site and report the offending register/value rather than crashing.
Example fix
// before
String raw = "0xFF"; // stored on the object -> parse fails
// after
String hex = raw.replaceFirst("(?i)^0x", "");
// store hex on the register object, then read via RegisterValueConverter Defensive patterns
Strategy: try-catch
Validate before calling
if (val instanceof String s && !s.matches("(?i)[0-9a-fA-F]+")) {
// strip '0x' / convert decimal->hex before storing
String clean = s.replaceFirst("(?i)^0x", "");
val = Long.toHexString(Long.parseLong(clean, 10));
} Type guard
static boolean isHexOnly(Object val) {
return val instanceof String s && s.matches("(?i)[0-9a-fA-F]+");
} Try / catch
try {
BigInteger v = new RegisterValueConverter(regVal).getValue();
} catch (RegisterValueException e) {
// log regVal.getParent().getPath() + e.getMessage(); treat register as unreadable
} Prevention
- Store register String values as bare hex (no '0x', no suffixes).
- Fix the target connector/emulator that writes non-hex register values.
- Validate value format at trace-load time.
When it happens
Trigger: Reading a TraceObjectValue for a register whose stored String value contains non-hex characters (e.g. '0x...', 'FFh', a decimal like '256', or whitespace), then calling RegisterValueConverter.getValue().
Common situations: Loading a trace from a target/connector that writes register values as decimal or with a '0x' prefix; hand-edited trace data; version/connector changes in the value format.
Related errors
- Address string should have at most one colon (:)
- Cannot convert register value: ({class}) '{val}'
- Register length is not numeric: ({class}) '{value}'
- More than one state is present in
- Section path must be a successor of this module's path
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/f712d3532ae71604.
Report an issue: GitHub.