{"record":{"id":"f19ce27d80fbeb78","repo":"gchq/CyberChef","slug":"error-invalid-base64-input-length-data-length","errorCode":null,"errorMessage":"Error: Invalid Base64 input length (${data.length}). Cannot be 4n+1, even without padding chars.","messagePattern":"Error: Invalid Base64 input length \\((.+?)\\)\\. Cannot be 4n\\+1, even without padding chars\\.","errorType":"validation","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/Base64.mjs","lineNumber":107,"sourceCode":"\n    alphabet = alphabet || \"A-Za-z0-9+/=\";\n    alphabet = Utils.expandAlphRange(alphabet).join(\"\");\n\n    // Confirm alphabet is a valid length\n    if (alphabet.length !== 64 && alphabet.length !== 65) { // Allow for padding\n        throw new OperationError(`Error: Base64 alphabet should be 64 characters long, or 65 with a padding character. Found ${alphabet.length}: ${alphabet}`);\n    }\n\n    // Remove non-alphabet characters\n    if (removeNonAlphChars) {\n        const re = new RegExp(\"[^\" + alphabet.replace(/[[\\]\\\\\\-^$]/g, \"\\\\$&\") + \"]\", \"g\");\n        data = data.replace(re, \"\");\n    }\n\n    if (strictMode) {\n        // Check for incorrect lengths (even without padding)\n        if (data.length % 4 === 1) {\n            throw new OperationError(`Error: Invalid Base64 input length (${data.length}). Cannot be 4n+1, even without padding chars.`);\n        }\n\n        if (alphabet.length === 65) { // Padding character included\n            const pad = alphabet.charAt(64);\n            const padPos = data.indexOf(pad);\n            if (padPos >= 0) {\n                // Check that the padding character is only used at the end and maximum of twice\n                if (padPos < data.length - 2 || data.charAt(data.length - 1) !== pad) {\n                    throw new OperationError(`Error: Base64 padding character (${pad}) not used in the correct place.`);\n                }\n\n                // Check that input is padded to the correct length\n                if (data.length % 4 !== 0) {\n                    throw new OperationError(\"Error: Base64 not padded to a multiple of 4.\");\n                }\n            }\n        }\n    }","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/Base64.mjs#L89-L125","documentation":"Thrown by fromBase64() in src/core/lib/Base64.mjs:107 when strictMode is enabled and the (post character-removal) input string has a length congruent to 1 modulo 4. Base64 packs 3 bytes into 4 characters, so a remainder of 1 is mathematically impossible for any validly-produced Base64 string, even with padding stripped. The check exists to reject truncated or corrupted input early instead of silently emitting wrong bytes.","triggerScenarios":"Calling fromBase64(data, alphabet, returnType, removeNonAlphChars, strictMode) with strictMode=true (5th arg) where, after non-alphabet chars are optionally stripped, data.length % 4 === 1. Example: fromBase64('SGVsbG8', 'A-Za-z0-9+/=', 'byteArray', true, true) after stripping yields length 7 (7%4===1). Also fires on lengths like 5, 9, 13, etc.","commonSituations":"Pasted Base64 that lost a character in transit (copy-paste truncation); concatenating Base64 fragments that split mid-quartet; stripping '=' padding AND a data char by accident; URL-safe variants where '-'/'_' got mangled before decoding; feeding hex or raw text that happens to be 4n+1 long while strictMode is on.","solutions":["Re-acquire the source Base64 string and verify its length is a multiple of 4 (or 4n+2 / 4n+3 when unpadded).","If you intentionally work with unpadded Base64, disable strictMode (pass false or omit the 5th argument).","Pad the string to a multiple of 4 with '=' characters before decoding when the alphabet includes padding.","Confirm removeNonAlphChars=true so stray whitespace/newlines are stripped before the length check."],"exampleFix":"// before - throws when a char was dropped\nfromBase64(truncatedStr, 'A-Za-z0-9+/=', 'byteArray', true, true);\n\n// after - tolerate unpadded/non-strict input\nfromBase64(truncatedStr, 'A-Za-z0-9+/=', 'byteArray', true, false);","handlingStrategy":"validation","validationCode":"function isValidBase64Length(data, removeNonAlphChars, alphabet) {\n  if (removeNonAlphChars) {\n    const re = new RegExp(\"[^\" + alphabet.replace(/[[\\]\\\\\\-^$]/g, \"\\\\$&\") + \"]\", \"g\");\n    data = data.replace(re, \"\");\n  }\n  return data.length % 4 !== 1;\n}\n// call: if (!isValidBase64Length(data, true, expandedAlphabet)) return null;","typeGuard":"function isPlausibleBase64(s) {\n  return typeof s === 'string' && s.length > 0 && s.replace(/[^A-Za-z0-9+/=]/g, '').length % 4 !== 1;\n}","tryCatchPattern":"try {\n  const bytes = fromBase64(input, alphabet, 'byteArray', true, true);\n} catch (e) {\n  if (e instanceof OperationError && /Invalid Base64 input length/.test(e.message)) {\n    // handle truncated/unpadded input\n  }\n}","preventionTips":["Default to strictMode=false unless you specifically need canonical-input rejection.","Strip whitespace and validate length modulo 4 before decoding.","Treat Base64 as binary data in transit; never hand-edit it."],"tags":["base64","decoding","input-validation","strict-mode"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}