gchq/CyberChef · error · OperationError

Invalid key length: ${key.length} bytes The following algor

Error message

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

What it means

AESEncrypt enforces the same AES key-size rule as the decryptor: the key, after conversion to a byte string, must be exactly 16, 24, or 32 bytes (AES-128/192/256). The check runs before any encryption work.

Source

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

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     *
     * @throws {OperationError} if invalid key length
     */
    run(input, args) {
        const key = Utils.convertToByteString(args[0].string, args[0].option),
            iv = Utils.convertToByteString(args[1].string, args[1].option),
            mode = args[2].split("/")[0],
            noPadding = args[2].endsWith("NoPadding"),
            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
        });

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Set the Key Format option to match the key representation (Hex for hex, Base64 for base64, UTF8 only for raw text).
  2. Verify the resulting byte length is exactly 16, 24, or 32.
  3. Derive passphrases through PBKDF2 or hash to a fixed length before using them as an AES key.

Example fix

// before: 16-byte raw key supplied with format Hex → 8 bytes, throws
// after: set Key Format to "UTF8" (or Latin1) for a raw 16-char key
Defensive patterns

Strategy: validation

Validate before calling

function validateAesKey(keyBytes) {
  if (![16, 24, 32].includes(keyBytes.length)) {
    throw new Error(`Key must be 16/24/32 bytes, got ${keyBytes.length}`);
  }
}

Type guard

function isAesKey(bytes) { return bytes instanceof Uint8Array && [16, 24, 32].includes(bytes.length); }

Try / catch

try { encryptAES(...); } catch (e) { if (/Invalid key length/.test(e.message)) {/* fix key format */} else throw e; }

Prevention

When it happens

Trigger: Utils.convertToByteString(args[0].string, args[0].option) yields a length outside {16, 24, 32}. Typically a Key Format option that does not match the supplied key text (Hex/UTF8/Base64 confusion), or a passphrase used directly as a key.

Common situations: Pasting a 32-char hex key while Key Format is UTF8 (→ 32 bytes / AES-256 instead of intended 16-byte AES-128); using a short password verbatim; key truncated in transit.

Related errors


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