gchq/CyberChef · error · OperationError
Invalid hexadecimal input. Length must be even.
Error message
Invalid hexadecimal input. Length must be even.
What it means
Thrown by Disassemble ARM run() when the hex string has an odd number of characters after whitespace removal. Each byte is two hex digits; an odd length means a half-byte is unpaired and cannot be parsed into a byte array. The check runs after the character-class check and after the empty-input early return.
Source
Thrown at src/core/operations/DisassembleARM.mjs:91
startAddress,
showHex,
showPosition
] = args;
// Remove whitespace from input
const hexInput = input.replace(/\s/g, "");
// Validate hex input
if (!/^[0-9a-fA-F]*$/.test(hexInput)) {
throw new OperationError("Invalid hexadecimal input. Please provide valid hex characters only.");
}
if (hexInput.length === 0) {
return "";
}
if (hexInput.length % 2 !== 0) {
throw new OperationError("Invalid hexadecimal input. Length must be even.");
}
// Convert hex string to byte array
const bytes = [];
for (let i = 0; i < hexInput.length; i += 2) {
bytes.push(parseInt(hexInput.substr(i, 2), 16));
}
// Determine architecture constant
let arch;
if (architecture === "ARM64 (AArch64)") {
arch = cs.ARCH_ARM64;
} else {
arch = cs.ARCH_ARM;
}
// Determine mode constant
let modeValue = cs.MODE_LITTLE_ENDIAN;View on GitHub (pinned to 4290ea7539)
Solutions
- Count the hex digits and pad/trim to an even length.
- If a leading nibble is missing, prepend '0' to the first byte (e.g. '1A3' -> '01A3').
- If the last nibble is spurious, drop it; if it is real, add its missing partner.
- Re-dump the bytes with a tool that emits two digits per byte.
Example fix
// before input: "90 00 00 1" // last byte missing a nibble -> odd length // after input: "90 00 00 14" // even length
Defensive patterns
Strategy: validation
Validate before calling
function isEvenLengthHex(s) {
const h = String(s).replace(/\s/g, "");
return /^[0-9a-fA-F]*$/.test(h) && h.length % 2 === 0;
} Type guard
/** @returns {boolean} */
function isEvenLengthHexString(s) {
const h = typeof s === "string" ? s.replace(/\s/g, "") : "";
return /^[0-9a-fA-F]*$/.test(h) && h.length % 2 === 0;
} Try / catch
try {
out = disassembleArm.run(input, args);
} catch (e) {
if (e instanceof OperationError && /Length must be even/.test(e.message)) {
// pad leading 0 or trim a stray trailing nibble
} else throw e;
} Prevention
- Ensure an even number of hex digits (two per byte).
- Prepend '0' if the first byte lost its leading nibble.
- Re-dump bytes with a tool that always emits two digits per byte.
- Re-count after copy-paste to catch truncated nibbles.
When it happens
Trigger: A hex string whose length % 2 != 0: a missing leading zero (e.g. '1A3' instead of '01A3' or '1A30'), a truncated copy-paste that drops one nibble, or a stray digit appended.
Common situations: Copy-paste truncation dropping the last nibble; dropping a leading '0' from the first byte; concatenating hex lines and losing a character at a join; OCR/typing error.
Related errors
- Invalid hexadecimal input. Please provide valid hex characte
- Byte length must be a positive integer
- Failed to initialise Capstone disassembler: ${e}
- No valid ${architecture} instructions found in input. The by
- Disassembly failed: ${e}
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/5ca497ceb52f89ff.
Report an issue: GitHub.