gchq/CyberChef · error · OperationError

Invalid Base64 alphabet length (${alphabet.length}): ${alpha

Error message

Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}

What it means

Thrown by toBase64() (Base64.mjs line 37) after Utils.expandAlphRange(alphabet).join('') when the resulting alphabet length is not 64 (or 65 with padding). expandAlphRange turns range shortcuts like 'A-Za-z0-9+/=' into the full character set; if the input is malformed or a different base's alphabet, the expanded length is wrong. Note toBase64 has NO fallback: an explicit '' alphabet expands to '' (length 0) and throws.

Source

Thrown at src/core/lib/Base64.mjs:37

 * @example
 * // returns "SGVsbG8="
 * toBase64([72, 101, 108, 108, 111]);
 *
 * // returns "SGVsbG8="
 * toBase64("Hello");
 */
export function toBase64(data, alphabet="A-Za-z0-9+/=") {
    if (!data) return "";
    if (typeof data == "string") {
        data = Utils.strToArrayBuffer(data);
    }
    if (data instanceof ArrayBuffer) {
        data = new Uint8Array(data);
    }

    alphabet = Utils.expandAlphRange(alphabet).join("");
    if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding
        throw new OperationError(`Invalid Base64 alphabet length (${alphabet.length}): ${alphabet}`);
    }

    let output = "",
        chr1, chr2, chr3,
        enc1, enc2, enc3, enc4,
        i = 0;

    while (i < data.length) {
        chr1 = data[i++];
        chr2 = data[i++];
        chr3 = data[i++];

        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;

        if (isNaN(chr2)) {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Use the default alphabet 'A-Za-z0-9+/=' (65 chars with padding) if you want standard Base64.
  2. Provide exactly 64 distinct chars, or 65 if you include a padding char as the 65th.
  3. If you need a different base, use the matching operation (To Base32/58/62/85), not Base64.

Example fix

// before
toBase64(data, 'A-Z0-9'); // 36 chars

// after
toBase64(data); // default standard alphabet
toBase64(data, 'A-Za-z0-9+/=');
Defensive patterns

Strategy: validation

Validate before calling

import Utils from './core/Utils.mjs';
function validB64Alphabet(a) {
  const len = Utils.expandAlphRange(a).join('').length;
  return len === 64 || len === 65;
}
// call before toBase64(data, alphabet)

Type guard

function isBase64Alphabet(a): boolean { const n = Utils.expandAlphRange(a).join('').length; return n === 64 || n === 65; }

Try / catch

try { toBase64(data, alphabet); } catch (e) {
  if (e instanceof OperationError && /Invalid Base64 alphabet length/.test(e.message)) { alphabet = 'A-Za-z0-9+/='; }
}

Prevention

When it happens

Trigger: Calling toBase64(data, 'A-Z0-9') (36 chars); passing a Base32/Base58/Base62 alphabet into the Base64 function; a typo like 'A-Za-z0-9+/' (63 chars, missing '='); an explicit empty-string alphabet.

Common situations: User supplies a custom alphabet in the 'To Base64' operation that is the wrong length; copying an alphabet from a different base operation; recipe using a custom alphabet that lost a character in transit.

Related errors


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