gchq/CyberChef · error · OperationError
Encoded string exceeds maximum length of 90 characters (got
Error message
Encoded string exceeds maximum length of 90 characters (got ${result.length}). Consider using smaller input data. What it means
Thrown by encode() in src/core/lib/Bech32.mjs:223 after building the result string if its total length exceeds 90 characters. BIP-0173 caps the entire Bech32 string (HRP + separator + data + checksum) at 90 characters; longer inputs would violate the specification and risk incompatibility across parsers. This is a final guard, checked after the checksum is appended.
Source
Thrown at src/core/lib/Bech32.mjs:223
// Witness version is kept as single 5-bit value, program is converted
words = [witnessVersion].concat(toWords(witnessProgram));
} else {
// Generic encoding: convert all bytes to 5-bit words
words = toWords(data);
}
// Create checksum
const checksum = createChecksum(hrpLower, words, encoding);
// Build result string
let result = hrpLower + "1";
for (const w of words.concat(checksum)) {
result += CHARSET[w];
}
// Check maximum length (90 characters)
if (result.length > 90) {
throw new OperationError(`Encoded string exceeds maximum length of 90 characters (got ${result.length}). Consider using smaller input data.`);
}
return result;
}
/**
* Decode a Bech32/Bech32m string
*
* @param {string} str - Bech32/Bech32m encoded string
* @param {string} encoding - "Bech32", "Bech32m", or "Auto-detect"
* @returns {{hrp: string, data: number[]}} - Decoded HRP and data bytes
*/
export function decode(str, encoding = "Auto-detect") {
// Check for empty input
if (!str || str.length === 0) {
throw new OperationError("Input cannot be empty.");
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Reduce the input data length so the final string is <= 90 characters.
- Use a shorter HRP.
- Split large payloads across multiple Bech32 strings if the use case allows.
- If you need arbitrary-length Base32-like encoding without the 90-char cap, use a different scheme (e.g. raw Base32).
Example fix
// before - payload too large for one Bech32 string
encode('bb', hugeByteArray, 'Bech32', false);
// after - chunk the payload
const chunks = chunkBytes(hugeByteArray, maxBytesForLimit);
const encoded = chunks.map(c => encode('bb', c, 'Bech32', false)); Defensive patterns
Strategy: validation
Validate before calling
function estimateBech32Length(hrp, dataLen, segwit) {
const programLen = segwit ? dataLen - 1 : dataLen;
const wordCount = Math.ceil((programLen * 8) / 5) + (segwit ? 1 : 0);
return hrp.length + 1 + wordCount + 6;
}
// if (estimateBech32Length(hrp, data.length, true) > 90) reject early; Type guard
function fitsBech32Limit(hrp, data, segwit) {
return estimateBech32Length(hrp, data.length, segwit) <= 90;
} Try / catch
try {
encode(hrp, data, 'Bech32', segwit);
} catch (e) {
if (e instanceof OperationError && /exceeds maximum length of 90/.test(e.message)) {
// split payload or shorten HRP
}
} Prevention
- Bech32 is for short identifiers (addresses), not bulk data encoding.
- Estimate the final length before encoding and reject oversized payloads.
- Use a shorter HRP or chunk large data across multiple strings.
When it happens
Trigger: encode(hrp, largeData, ...) where hrp.length + 1 + ceil(data.length*8/5) + 6 > 90. For example, a long HRP combined with a 40-byte program, or generic (non-segwit) encoding of a >50-byte payload.
Common situations: Encoding arbitrary large data (not a Bitcoin address) into Bech32 and hitting the spec limit; very long HRP chosen by the caller; trying to embed a full transaction or message in a single Bech32 string instead of chunking.
Related errors
- Invalid Bech32 string: exceeds maximum length of 90 characte
- Invalid padding: too many bits remaining
- Human-Readable Part (HRP) cannot be empty.
- HRP contains invalid character at position ${i}. Only printa
- Invalid witness version: ${witnessVersion}. Must be 0-16.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/085e71feaedd0ea1.
Report an issue: GitHub.