gchq/CyberChef · error · OperationError

Input length must be a multiple of 16 bytes for NoPadding mo

Error message

Input length must be a multiple of 16 bytes for NoPadding modes.

What it means

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.

Source

Thrown at src/core/operations/AESEncrypt.mjs:135

            inputType = args[3],
            outputType = args[4],
            aad = Utils.convertToByteString(args[5].string, args[5].option),
            includeIV = args[6];

        if ([16, 24, 32].indexOf(key.length) < 0) {
            throw new OperationError(`Invalid key length: ${key.length} bytes

The following algorithms will be used based on the size of the key:
  16 bytes = AES-128
  24 bytes = AES-192
  32 bytes = AES-256`);
        }

        input = Utils.convertToByteString(input, inputType);

        // Handle NoPadding modes
        if (noPadding && input.length % 16 !== 0) {
            throw new OperationError("Input length must be a multiple of 16 bytes for NoPadding modes.");
        }
        const cipher = forge.cipher.createCipher("AES-" + mode, key);
        cipher.start({
            iv: iv,
            additionalData: mode === "GCM" ? aad : undefined
        });
        if (noPadding) {
            cipher.mode.pad = function (output, options) {
                return true;
            };
        }
        cipher.update(forge.util.createBuffer(input));
        cipher.finish();

        let output = cipher.output.getBytes();

        if (includeIV === "Prepend") {
            output = iv + output;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Pad the plaintext to a multiple of 16 bytes beforehand (PKCS#7, zero-padding, or space-padding per your protocol).
  2. Switch to a padded mode (e.g. 'CBC' defaulting to PKCS#7) and let the library pad.
  3. Use a stream mode ('GCM', 'CTR', 'CFB', 'OFB') which has no block-alignment requirement.

Example fix

// before: mode 'CBC/NoPadding', plaintext 10 bytes → throws
// after: pad to 16 bytes
const padLen = 16 - (plain.length % 16);
plain = plain + '\x00'.repeat(padLen); // zero pad to a block boundary
Defensive patterns

Strategy: validation

Validate before calling

function ensureBlockAligned(plainBytes, block = 16) {
  if (plainBytes.length % block !== 0) {
    throw new Error(`NoPadding requires multiple of ${block} bytes, got ${plainBytes.length}`);
  }
}

Type guard

function isBlockAligned(bytes, block = 16) { return bytes.length % block === 0; }

Try / catch

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; }

Prevention

When it happens

Trigger: args[2] (mode string) ends with 'NoPadding' (e.g. 'CBC/NoPadding', 'ECB/NoPadding') and the plaintext byte length is not divisible by 16.

Common situations: 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.

Related errors


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