gchq/CyberChef · error · OperationError

Invalid Bech32 string: exceeds maximum length of 90 characte

Error message

Invalid Bech32 string: exceeds maximum length of 90 characters (got ${str.length}).

What it means

Thrown by decode() in src/core/lib/Bech32.mjs:244 when the input string is longer than 90 characters. BIP-0173 mandates a 90-character maximum for the entire Bech32 string; longer input cannot be a valid Bech32/Bech32m address and is rejected before any parsing work. This is the second early gate, right after the empty-input check.

Source

Thrown at src/core/lib/Bech32.mjs:244

    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.");
    }

    // Check maximum length
    if (str.length > 90) {
        throw new OperationError(`Invalid Bech32 string: exceeds maximum length of 90 characters (got ${str.length}).`);
    }

    // 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.");
    }

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Trim the input: str = str.trim() before decoding.
  2. Verify you are decoding a single Bech32 address, not a block of text.
  3. If the input is legitimately long, it is not Bech32 — pick the right decoder.
  4. Surface the actual length to the user to help them spot the extra characters.

Example fix

// before - trailing whitespace pushes length over 90
decode(rawPasted);

// after - trim first
decode(rawPasted.trim());
Defensive patterns

Strategy: validation

Validate before calling

function normalizeBech32Input(str) {
  if (typeof str !== 'string') throw new TypeError('Expected string');
  const trimmed = str.trim();
  if (trimmed.length > 90) throw new RangeError(`Input too long (${trimmed.length} > 90)`);
  return trimmed;
}

Type guard

function isWithinBech32Limit(s) {
  return typeof s === 'string' && s.trim().length <= 90;
}

Try / catch

try {
  decode(raw);
} catch (e) {
  if (e instanceof OperationError && /exceeds maximum length of 90/.test(e.message)) {
    raw = raw.trim(); // retry once after trimming whitespace
  }
}

Prevention

When it happens

Trigger: decode(str) where str.length === 91 or more. Common with concatenated addresses, addresses with trailing whitespace when whitespace is counted, or arbitrary text mistakenly fed in.

Common situations: Trailing newline/whitespace not trimmed before the length check; two addresses concatenated; pasting an address plus surrounding text from a document; an address from a chain that uses a longer format mistaken for Bech32.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/75417d8f4fd43ee2. Report an issue: GitHub.