{"record":{"id":"55df5a17e2816dec","repo":"gchq/CyberChef","slug":"error-base64-input-contains-non-alphabet-char-s","errorCode":null,"errorMessage":"Error: Base64 input contains non-alphabet char(s)","messagePattern":"Error: Base64 input contains non-alphabet char\\(s\\)","errorType":"validation","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/Base64.mjs","lineNumber":140,"sourceCode":"                }\n            }\n        }\n    }\n\n    const output = [];\n    let chr1, chr2, chr3,\n        enc1, enc2, enc3, enc4,\n        i = 0;\n\n    while (i < data.length) {\n        // Including `|| null` forces empty strings to null so that indexOf returns -1 instead of 0\n        enc1 = alphabet.indexOf(data.charAt(i++) || null);\n        enc2 = alphabet.indexOf(data.charAt(i++) || null);\n        enc3 = alphabet.indexOf(data.charAt(i++) || null);\n        enc4 = alphabet.indexOf(data.charAt(i++) || null);\n\n        if (strictMode && (enc1 < 0 || enc2 < 0 || enc3 < 0 || enc4 < 0)) {\n            throw new OperationError(\"Error: Base64 input contains non-alphabet char(s)\");\n        }\n\n        chr1 = (enc1 << 2) | (enc2 >> 4);\n        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n        chr3 = ((enc3 & 3) << 6) | enc4;\n\n        if (chr1 >= 0 && chr1 < 256) {\n            output.push(chr1);\n        }\n        if (chr2 >= 0 && chr2 < 256 && enc3 !== 64) {\n            output.push(chr2);\n        }\n        if (chr3 >= 0 && chr3 < 256 && enc4 !== 64) {\n            output.push(chr3);\n        }\n    }\n\n    return returnType === \"string\" ? Utils.byteArrayToUtf8(output) : output;","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/Base64.mjs#L122-L158","documentation":"Thrown by fromBase64() in src/core/lib/Base64.mjs:140 during the decode loop, under strictMode, when alphabet.indexOf() returns -1 for any of the four quartet characters — meaning a byte survived into the loop that is not in the alphabet (including the pad slot). Because the earlier removeNonAlphChars pass strips everything outside the alphabet+pad, this error in practice requires removeNonAlphChars=false so that foreign characters reach the decoder.","triggerScenarios":"fromBase64(data, alphabet, returnType, removeNonAlphChars=false, strictMode=true) where data contains any char not in the expanded alphabet. Example: fromBase64('AB CD', 'A-Za-z0-9+/=', 'byteArray', false, true) — the space is not in the alphabet, indexOf returns -1, throws.","commonSituations":"Whitespace or newlines in pasted Base64 when the caller explicitly disabled character removal; mixing alphabets (e.g. url-safe '-/_' fed to the standard alphabet); embedded null bytes or BOM; binary data mistakenly treated as a Base64 string.","solutions":["Pass removeNonAlphChars=true (the default) so out-of-alphabet characters are stripped before decoding.","Pre-trim the input: data.replace(/[^A-Za-z0-9+/=]/g, '') for the standard alphabet.","Verify the alphabet option matches how the string was produced (Standard vs URL-safe vs itoa64).","If you genuinely need strict rejection, keep strictMode=true but clean the input first."],"exampleFix":"// before - space not in alphabet, removal disabled\nfromBase64('AB CD', 'A-Za-z0-9+/=', 'byteArray', false, true);\n\n// after - let the library strip non-alphabet chars\nfromBase64('AB CD', 'A-Za-z0-9+/=', 'byteArray', true, true);","handlingStrategy":"validation","validationCode":"function containsOnlyAlphabet(data, alphabet) {\n  for (const ch of data) {\n    if (alphabet.indexOf(ch) < 0) return false;\n  }\n  return true;\n}\n// or simply pass removeNonAlphChars=true to fromBase64","typeGuard":"function isPureStandardBase64(s) {\n  return typeof s === 'string' && /^[A-Za-z0-9+/=]*$/.test(s);\n}","tryCatchPattern":"try {\n  fromBase64(input, 'A-Za-z0-9+/=', 'byteArray', false, true);\n} catch (e) {\n  if (e instanceof OperationError && /non-alphabet char/.test(e.message)) {\n    input = input.replace(/[^A-Za-z0-9+/=]/g, '');\n  }\n}","preventionTips":["Keep removeNonAlphChars at its default true unless you have a specific reason.","If you disable removal, pre-sanitize the input to the chosen alphabet.","Match the alphabet option to how the data was encoded."],"tags":["base64","decoding","alphabet","strict-mode","input-validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}