gchq/CyberChef · error · OperationError
Invalid Bech32 string: Human-Readable Part (HRP) cannot be e
Error message
Invalid Bech32 string: Human-Readable Part (HRP) cannot be empty.
What it means
Thrown by decode() in src/core/lib/Bech32.mjs:264 when the rightmost '1' separator is at index 0 — meaning nothing precedes it and the HRP is empty. This is the decode-side counterpart of the encode-side empty-HRP guard; an empty HRP makes checksum verification meaningless because the HRP contributes to polymod via hrpExpand.
Source
Thrown at src/core/lib/Bech32.mjs:264
// Check for mixed case
const hasUpper = /[A-Z]/.test(str);
const hasLower = /[a-z]/.test(str);
if (hasUpper && hasLower) {
throw new OperationError("Invalid Bech32 string: mixed case is not allowed. Use all uppercase or all lowercase.");
}
// Convert to lowercase for processing
str = str.toLowerCase();
// Find separator (last occurrence of '1')
const sepIndex = str.lastIndexOf("1");
if (sepIndex === -1) {
throw new OperationError("Invalid Bech32 string: no separator '1' found.");
}
if (sepIndex === 0) {
throw new OperationError("Invalid Bech32 string: Human-Readable Part (HRP) cannot be empty.");
}
if (sepIndex + 7 > str.length) {
throw new OperationError("Invalid Bech32 string: data part is too short (minimum 6 characters for checksum).");
}
// Extract HRP and data part
const hrp = str.substring(0, sepIndex);
const dataPart = str.substring(sepIndex + 1);
// Validate HRP characters
for (let i = 0; i < hrp.length; i++) {
const c = hrp.charCodeAt(i);
if (c < 33 || c > 126) {
throw new OperationError(`HRP contains invalid character at position ${i}.`);
}
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Pass the complete Bech32 string including its HRP prefix (e.g. 'bc1q...').
- If the HRP was stripped, re-prepend the correct HRP and '1' before decoding.
- Validate that the string starts with a known HRP ('bc', 'tb', 'bcrt', etc.) before decoding.
- Audit any pre-processing that might have truncated the prefix.
Example fix
// before - HRP stripped, separator at index 0
decode('1qwl3q4l');
// after - include the HRP
decode('bc1qwl3q4l...'); Defensive patterns
Strategy: validation
Validate before calling
function requireHrpPrefix(str) {
const sep = str.lastIndexOf('1');
if (sep <= 0) throw new Error('Bech32 string missing HRP before separator');
return str;
} Type guard
function hasNonEmptyHrpBeforeSeparator(s) {
const i = typeof s === 'string' ? s.lastIndexOf('1') : -1;
return i > 0;
} Try / catch
try {
decode(input);
} catch (e) {
if (e instanceof OperationError && /HRP.*cannot be empty/.test(e.message)) {
// re-prepend the correct HRP + '1'
}
} Prevention
- Always pass the full address including its HRP prefix.
- Validate the string starts with a known HRP ('bc', 'tb', 'bcrt', ...).
- Avoid pre-processing that could strip the prefix.
When it happens
Trigger: decode('1qwerty...') where the string starts with '1'. Reached after the separator is found (sepIndex !== -1) but equals zero. Happens when the HRP was stripped, leaving the separator as the first character.
Common situations: User pasted only the data+checksum part without the HRP; a regex or formatter deleted the HRP prefix; an address from a chain whose HRP the user removed expecting it to be implicit; confused variable holding dataPart instead of the full string.
Related errors
- Invalid Bech32 string: no separator '1' found.
- Invalid padding: too many bits remaining
- Human-Readable Part (HRP) cannot be empty.
- HRP contains invalid character at position ${i}. Only printa
- Input cannot be empty.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/27499749651d76e4.
Report an issue: GitHub.