gchq/CyberChef · error · OperationError

Invalid nonce length: ${nonce.length} bytes. ChaCha uses a

Error message

Invalid nonce length: ${nonce.length} bytes.

ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).

What it means

Thrown by the ChaCha operation when a user-supplied nonce (non-Integer nonce type) does not decode to exactly 8 or 12 bytes. ChaCha accepts a 64-bit (8-byte) or 96-bit (12-byte) nonce; the counter occupies the remaining bytes of the 16-byte counter+nonce block.

Source

Thrown at src/core/operations/ChaCha.mjs:170

            nonceType = args[1].option,
            rounds = parseInt(args[3], 10),
            inputType = args[4],
            outputType = args[5];

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

ChaCha uses a key of 16 or 32 bytes (128 or 256 bits).`);
        }

        let counter, nonce, counterLength;
        if (nonceType === "Integer") {
            nonce = Utils.intToByteArray(parseInt(args[1].string, 10), 12, "little");
            counterLength = 4;
        } else {
            nonce = Utils.convertToByteArray(args[1].string, args[1].option);
            if (!(nonce.length === 12 || nonce.length === 8)) {
                throw new OperationError(`Invalid nonce length: ${nonce.length} bytes.

ChaCha uses a nonce of 8 or 12 bytes (64 or 96 bits).`);
            }
            counterLength = 16 - nonce.length;
        }
        counter = Utils.intToByteArray(args[2], counterLength, "little");

        const output = [];
        input = Utils.convertToByteArray(input, inputType);

        let counterAsInt = Utils.byteArrayToInt(counter, "little");
        for (let i = 0; i < input.length; i += 64) {
            counter = Utils.intToByteArray(counterAsInt, counterLength, "little");
            const stream = chacha(key, nonce, counter, rounds);
            for (let j = 0; j < 64 && i + j < input.length; j++) {
                output.push(input[i + j] ^ stream[j]);
            }
            counterAsInt++;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Supply exactly 8 bytes (16 hex chars) or 12 bytes (24 hex chars) for the nonce.
  2. Match the nonce input option to its encoding (Hex/Base64).
  3. If you only have an integer nonce, set nonceType to 'Integer' to let the operation size it to 12 bytes.
  4. Ensure counter length = 16 − nonce length fits the algorithm variant you intend.

Example fix

// before — nonce hex "010203040506070809" = 9 bytes, throws
// after — 12 bytes
// nonce (hex): "0102030405060708090a0b0c"
Defensive patterns

Strategy: validation

Validate before calling

if (nonceType !== "Integer") {
  const nonce = Utils.convertToByteArray(args[1].string, args[1].option);
  if (!(nonce.length === 12 || nonce.length === 8)) { /* reject before run */ }
}

Type guard

function isValidChaChaNonce(nonce) { return nonce.length === 8 || nonce.length === 12; }

Try / catch

null

Prevention

When it happens

Trigger: ChaCha.run with nonceType !== 'Integer' calls Utils.convertToByteArray on args[1].string; if the result is not length 8 or 12, it throws. Wrong-length hex (not 16/24 chars), wrong Base64 length, or UTF-8 nonce text triggers it. Note: when nonceType === 'Integer' this check is skipped (the integer is forced to 12 bytes).

Common situations: User mixes up nonce formats — supplies a 16-byte (32-hex) IV from AES-GCM expecting it to work, uses a 6-byte nonce, or pastes nonce text as UTF-8 instead of hex.

Related errors


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