gchq/CyberChef · error · OperationError

Alphabet must be of length 58

Error message

Alphabet must be of length 58

What it means

Thrown by From Base58 when the supplied alphabet, after expandAlphRange expansion, does not have exactly 58 unique characters. Base58 by definition requires a 58-symbol alphabet; both the length and uniqueness are checked. This is an argument/configuration error, independent of the input data.

Source

Thrown at src/core/operations/FromBase58.mjs:69

            },
        ];
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {byteArray}
     */
    run(input, args) {
        let alphabet = args[0] || ALPHABET_OPTIONS[0].value;
        const removeNonAlphaChars = args[1] === undefined ? true : args[1],
            result = [];

        alphabet = Utils.expandAlphRange(alphabet).join("");

        if (alphabet.length !== 58 ||
            [].unique.call(alphabet).length !== 58) {
            throw new OperationError("Alphabet must be of length 58");
        }

        if (input.length === 0) return [];

        let zeroPrefix = 0;
        for (let i = 0; i < input.length && input[i] === alphabet[0]; i++) {
            zeroPrefix++;
        }

        [].forEach.call(input, function(c, charIndex) {
            const index = alphabet.indexOf(c);

            if (index === -1) {
                if (removeNonAlphaChars) {
                    return;
                } else {
                    throw new OperationError(`Char '${c}' at position ${charIndex} not in alphabet`);
                }

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Use one of the built-in alphabet presets (Bitcoin, Ripple) instead of a custom one.
  2. If custom, ensure exactly 58 unique characters with no duplicates.
  3. Double-check expandAlphRange semantics if using ranges like A-Z.

Example fix

// before: 57-char alphabet
fromBase58.run(input, ['123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuv']) // 57
// after: standard Bitcoin alphabet (58 unique)
fromBase58.run(input, ['123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'])
Defensive patterns

Strategy: validation

Validate before calling

const alphabet = Utils.expandAlphRange(args[0]).join('');
const unique = new Set(alphabet.split(''));
if (alphabet.length !== 58 || unique.size !== 58) {
  // use a built-in preset; do not call fromBase58.run()
}

Type guard

function isValidBase58Alphabet(a) {
  const s = a; // post-expansion string
  return s.length === 58 && new Set(s).size === 58;
}

Try / catch

try {
  fromBase58.run(input, args);
} catch (e) {
  if (e.type === 'OperationError' && /Alphabet must be of length 58/.test(e.message)) {
    // reset alphabet to the Bitcoin/Ripple preset
  } else throw e;
}

Prevention

When it happens

Trigger: Providing a custom alphabet with fewer or more than 58 chars; an alphabet with duplicate characters; an A-Z range expansion that produced unexpected length; selecting a preset then editing it down.

Common situations: User customizes the alphabet field incorrectly; confusion between Bitcoin and Ripple alphabets mixed together; copy-paste truncation of the alphabet string.

Related errors


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