{"record":{"id":"1a0e23ef0f08c810","repo":"gchq/CyberChef","slug":"input-length-must-be-a-multiple-of-16-bytes-for-no","errorCode":null,"errorMessage":"Input length must be a multiple of 16 bytes for NoPadding modes.","messagePattern":"Input length must be a multiple of 16 bytes for NoPadding modes\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/AESEncrypt.mjs","lineNumber":135,"sourceCode":"            inputType = args[3],\n            outputType = args[4],\n            aad = Utils.convertToByteString(args[5].string, args[5].option),\n            includeIV = args[6];\n\n        if ([16, 24, 32].indexOf(key.length) < 0) {\n            throw new OperationError(`Invalid key length: ${key.length} bytes\n\nThe following algorithms will be used based on the size of the key:\n  16 bytes = AES-128\n  24 bytes = AES-192\n  32 bytes = AES-256`);\n        }\n\n        input = Utils.convertToByteString(input, inputType);\n\n        // Handle NoPadding modes\n        if (noPadding && input.length % 16 !== 0) {\n            throw new OperationError(\"Input length must be a multiple of 16 bytes for NoPadding modes.\");\n        }\n        const cipher = forge.cipher.createCipher(\"AES-\" + mode, key);\n        cipher.start({\n            iv: iv,\n            additionalData: mode === \"GCM\" ? aad : undefined\n        });\n        if (noPadding) {\n            cipher.mode.pad = function (output, options) {\n                return true;\n            };\n        }\n        cipher.update(forge.util.createBuffer(input));\n        cipher.finish();\n\n        let output = cipher.output.getBytes();\n\n        if (includeIV === \"Prepend\") {\n            output = iv + output;","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/AESEncrypt.mjs#L117-L153","documentation":"When a 'NoPadding' cipher mode is selected, AES operates in plain block mode and the plaintext must be an exact multiple of the 16-byte block. AESEncrypt throws this if noPadding is true and input.length % 16 !== 0. Stream-like modes (GCM, CTR, CFB, OFB) and padded modes (CBC, ECB with PKCS#7) do not have this requirement.","triggerScenarios":"args[2] (mode string) ends with 'NoPadding' (e.g. 'CBC/NoPadding', 'ECB/NoPadding') and the plaintext byte length is not divisible by 16.","commonSituations":"Selecting a NoPadding variant to match another tool but forgetting to pre-pad the plaintext; arbitrary-length binary data fed into ECB/CBC NoPadding; user expects zero-padding but the operation does not auto-pad in NoPadding mode.","solutions":["Pad the plaintext to a multiple of 16 bytes beforehand (PKCS#7, zero-padding, or space-padding per your protocol).","Switch to a padded mode (e.g. 'CBC' defaulting to PKCS#7) and let the library pad.","Use a stream mode ('GCM', 'CTR', 'CFB', 'OFB') which has no block-alignment requirement."],"exampleFix":"// before: mode 'CBC/NoPadding', plaintext 10 bytes → throws\n// after: pad to 16 bytes\nconst padLen = 16 - (plain.length % 16);\nplain = plain + '\\x00'.repeat(padLen); // zero pad to a block boundary","handlingStrategy":"validation","validationCode":"function ensureBlockAligned(plainBytes, block = 16) {\n  if (plainBytes.length % block !== 0) {\n    throw new Error(`NoPadding requires multiple of ${block} bytes, got ${plainBytes.length}`);\n  }\n}","typeGuard":"function isBlockAligned(bytes, block = 16) { return bytes.length % block === 0; }","tryCatchPattern":"try { encryptAES(plain, key, 'CBC/NoPadding'); } catch (e) { if (/multiple of 16 bytes/.test(e.message)) {/* pad or switch to padded mode */} else throw e; }","preventionTips":["Pre-pad plaintext to a 16-byte multiple when using NoPadding.","Prefer a padded mode unless your protocol mandates NoPadding.","Use GCM/CTR/CFB/OFB for arbitrary-length plaintext."],"tags":["aes","padding","validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}