gchq/CyberChef · error · OperationError

Invalid key length: ${key.length} bytes XTEA requires a key

Error message

Invalid key length: ${key.length} bytes

XTEA requires a key length of 16 bytes (128 bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).

What it means

Thrown by XTEAEncrypt.run when the converted key byte array is not exactly 16 bytes. Identical guard to the decrypt operation: XTEA requires a 128-bit key; encryption aborts before IV/rounds checks if the length differs from 16.

Source

Thrown at src/core/operations/XTEAEncrypt.mjs:84

                "value": 32,
                "min": 1,
                "max": 255
            }
        ];
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        const key = Utils.convertToByteArray(args[0].string, args[0].option),
            iv = Utils.convertToByteArray(args[1].string, args[1].option),
            [,, mode, inputType, outputType, padding, rounds] = args;

        if (key.length !== 16)
            throw new OperationError(`Invalid key length: ${key.length} bytes

XTEA requires a key length of 16 bytes (128 bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);

        if (iv.length !== TEA_BLOCK_SIZE && iv.length !== 0 && mode !== "ECB")
            throw new OperationError(`Invalid IV length: ${iv.length} bytes

XTEA uses an IV length of ${TEA_BLOCK_SIZE} bytes (${TEA_BLOCK_SIZE * 8} bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);

        if (!Number.isInteger(rounds) || rounds < 1 || rounds > 255)
            throw new OperationError(`Invalid number of rounds: ${rounds}

Rounds must be an integer between 1 and 255. Standard XTEA uses 32 rounds.`);

        // Default IV to null bytes if empty (like AES)
        const actualIv = iv.length === 0 ? new Array(TEA_BLOCK_SIZE).fill(0) : iv;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Make the decoded key exactly 16 bytes (32 hex chars or 16 UTF8 bytes).
  2. Match the key format option to the actual encoding.
  3. Derive a 128-bit key from a passphrase via a KDF if needed.

Example fix

// before: wrong format, key measures to !=16 bytes
args:[{string:"my-short-key",option:"Hex"}, ...]
// after
args:[{string:"0123456789abcdef0123456789abcdef",option:"Hex"}, ...]
Defensive patterns

Strategy: validation

Validate before calling

function xteaKeyRecipe(keyStr, keyOption) {
  const key = Utils.convertToByteArray(keyStr, keyOption);
  if (key.length !== 16) throw new Error(`XTEA key must be 16 bytes, got ${key.length}`);
  return {string:keyStr, option:keyOption};
}

Type guard

const isXteaKeyLen = (bytes) => bytes.length === 16;

Try / catch

try { chef.bake(data, recipe); } catch (e) { if (/key length/.test(e.message) && /XTEA/.test(e.message)) { /* fix key */ } else throw e; }

Prevention

When it happens

Trigger: args[0].string decoded via args[0].option is not 16 bytes. Same encoding/format pitfalls as XTEADecrypt.

Common situations: Wrong key format option; key measured in characters; using a short passphrase directly instead of a derived 128-bit key.

Related errors


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