gchq/CyberChef · error · OperationError

Error: Base64 not padded to a multiple of 4.

Error message

Error: Base64 not padded to a multiple of 4.

What it means

Thrown by fromBase64() in src/core/lib/Base64.mjs:121 under strictMode when a padding character is present and correctly positioned at the end, but the total input length is not a multiple of 4. Valid Base64 with padding is always a multiple of 4 characters; a remainder indicates missing or excess characters. This guard runs after the position check at line 115.

Source

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

    if (strictMode) {
        // Check for incorrect lengths (even without padding)
        if (data.length % 4 === 1) {
            throw new OperationError(`Error: Invalid Base64 input length (${data.length}). Cannot be 4n+1, even without padding chars.`);
        }

        if (alphabet.length === 65) { // Padding character included
            const pad = alphabet.charAt(64);
            const padPos = data.indexOf(pad);
            if (padPos >= 0) {
                // Check that the padding character is only used at the end and maximum of twice
                if (padPos < data.length - 2 || data.charAt(data.length - 1) !== pad) {
                    throw new OperationError(`Error: Base64 padding character (${pad}) not used in the correct place.`);
                }

                // Check that input is padded to the correct length
                if (data.length % 4 !== 0) {
                    throw new OperationError("Error: Base64 not padded to a multiple of 4.");
                }
            }
        }
    }

    const output = [];
    let chr1, chr2, chr3,
        enc1, enc2, enc3, enc4,
        i = 0;

    while (i < data.length) {
        // Including `|| null` forces empty strings to null so that indexOf returns -1 instead of 0
        enc1 = alphabet.indexOf(data.charAt(i++) || null);
        enc2 = alphabet.indexOf(data.charAt(i++) || null);
        enc3 = alphabet.indexOf(data.charAt(i++) || null);
        enc4 = alphabet.indexOf(data.charAt(i++) || null);

        if (strictMode && (enc1 < 0 || enc2 < 0 || enc3 < 0 || enc4 < 0)) {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Strip whitespace/newlines with removeNonAlphChars=true before the length check.
  2. Re-derive the string from the source and re-pad so total length % 4 === 0.
  3. If the input is meant to be unpadded, remove the '=' entirely rather than leaving a malformed pad.
  4. Fall back to strictMode=false when you cannot guarantee canonical padding.

Example fix

// before - length 6 is not a multiple of 4
fromBase64('ABCDE=', 'A-Za-z0-9+/=', 'byteArray', false, true);

// after - pad to a multiple of 4
fromBase64('ABCDEF==', 'A-Za-z0-9+/=', 'byteArray', false, true); // wait, still wrong
// correct: re-encode or use a canonical string of length %4===0
fromBase64(canonicalStr, 'A-Za-z0-9+/=', 'byteArray', true, true);
Defensive patterns

Strategy: validation

Validate before calling

function isPaddedToMultipleOf4(data, pad) {
  return data.indexOf(pad) < 0 || data.length % 4 === 0;
}

Type guard

function isCanonicalBase64WithPad(s) {
  return typeof s === 'string' && (s.indexOf('=') < 0 || (s.length % 4 === 0 && /^[A-Za-z0-9+/]+={0,2}$/.test(s)));
}

Try / catch

try {
  fromBase64(input, 'A-Za-z0-9+/=', 'byteArray', false, true);
} catch (e) {
  if (e instanceof OperationError && /not padded to a multiple of 4/.test(e.message)) {
    input = input.replace(/=+$/, ''); // strip and re-pad correctly
    while (input.length % 4 !== 0) input += '=';
  }
}

Prevention

When it happens

Trigger: strictMode=true, alphabet length 65, pad present at the tail, but data.length % 4 !== 0. Example: fromBase64('ABC=', 'A-Za-z0-9+/=', 'byteArray', false, true) — length 4 passes, but fromBase64('ABCDE=', ..., true) length 6 % 4 === 2 throws. Also 'A=' (length 2) or 'ABCDEFG=' (length 8 is fine; length 7 not).

Common situations: Trailing whitespace counted because removeNonAlphChars=false; partial truncation that left a dangling '='; copy-paste that duplicated or dropped a char between the data and the pad; user-added '=' to 'fix' an unpadded string without extending to a multiple of 4.

Related errors


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