gchq/CyberChef · error · OperationError

Input is too short to contain an IV of ${ivLength} bytes.

Error message

Input is too short to contain an IV of ${ivLength} bytes.

What it means

When AESDecrypt is configured to read the IV from the input ('From start' or 'From end'), the ciphertext must be strictly longer than ivLength bytes so that at least one byte of actual ciphertext remains after the IV is sliced off. This guard rejects inputs that are too short to contain both an IV and any ciphertext.

Source

Thrown at src/core/operations/AESDecrypt.mjs:164

            gcmTag = Utils.convertToByteString(args[6].string, args[6].option),
            aad = Utils.convertToByteString(args[7].string, args[7].option),
            ivFromInput = args[8];


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

        if (ivFromInput !== "Off") {
            if (input.length <= ivLength) {
                throw new OperationError(`Input is too short to contain an IV of ${ivLength} bytes.`);
            }

            if (ivFromInput === "From start") {
                iv = input.substr(0, ivLength);
                input = input.substr(ivLength);
            } else {
                iv = input.substr(input.length - ivLength);
                input = input.substr(0, input.length - ivLength);
            }
        } else {
            iv = Utils.convertToByteString(args[1].string, args[1].option);
        }

        const decipher = forge.cipher.createDecipher("AES-" + mode, key);

        /* Allow for a "no padding" mode */
        if (noPadding) {
            decipher.mode.unpad = function (output, options) {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide the full blob exactly as output by the encryptor (IV concatenated with ciphertext).
  2. If the IV is supplied separately, set IV From Input to 'Off' and pass the IV in the IV argument.
  3. Set ivLength (args[2]) to the correct value (16 for AES-CBC IV, 12 for a typical GCM nonce).
  4. Re-encrypt a fresh sample and confirm the prepended/appended IV length matches ivLength.

Example fix

// before: ivFromInput='From start', ivLength=16, input is 16 bytes → throws
// after: supply input = IV(16) + ciphertext(>=1 block) so total > 16
Defensive patterns

Strategy: validation

Validate before calling

function assertInputHasIvRoom(inputBytes, ivLength) {
  if (inputBytes.length <= ivLength) {
    throw new Error(`Input (${inputBytes.length}B) too short for IV of ${ivLength}B`);
  }
}

Type guard

function inputContainsIv(bytes, ivLength) { return bytes.length > ivLength; }

Try / catch

try { decryptAES(...); } catch (e) { if (/too short to contain an IV/.test(e.message)) {/* supply full ciphertext or switch IV mode off */} else throw e; }

Prevention

When it happens

Trigger: args[8] (ivFromInput) is not 'Off', and input.length <= ivLength (args[2], typically 16 for AES-CBC or 12 for GCM nonce scenarios). For example, feeding a 16-byte blob with IV 'From start' and ivLength 16 leaves nothing to decrypt.

Common situations: The IV was not actually prepended/appended to the ciphertext during encryption; the ciphertext was truncated; ivLength was set to a value larger than what the encryptor used; confusion between GCM 12-byte nonce and CBC 16-byte IV.

Related errors


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