gchq/CyberChef · error · OperationError

The key must be exactly 32 bytes long

Error message

The key must be exactly 32 bytes long

What it means

Thrown by BLAKE3.run when a non-empty key is supplied whose decoded length is not exactly 32 bytes. Unlike BLAKE2b/2s which accept a range of key sizes up to a maximum, BLAKE3's keyed mode requires a fixed 32-byte (256-bit) key; any other non-empty length is rejected. An empty key string is allowed and triggers unkeyed hashing.

Solutions

  1. Provide exactly 32 bytes of key material (64 hex chars), or leave the key empty for unkeyed hashing.
  2. Derive a 32-byte key from a passphrase using a KDF before BLAKE3.
  3. Confirm the key input option matches the encoding.

Example fix

// before - 16-byte key
chef.blake3(input, { key: "00112233445566778899aabbccddeeff", keyOption: "Hex" });

// after - exactly 32 bytes
chef.blake3(input, { key: "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", keyOption: "Hex" });
Defensive patterns

Strategy: validation

Validate before calling

function assertBlake3Key(keyStr, keyOption) {
  if (keyStr === "" || keyStr == null) return null;
  const bytes = Utils.convertToByteArray(keyStr, keyOption);
  if (bytes.length !== 32) throw new Error(`BLAKE3 key must be exactly 32 bytes, got ${bytes.length}`);
  return bytes;
}
assertBlake3Key(key, keyOption);

Type guard

function isExactly32ByteHex(s) { return /^[0-9a-f]{64}$/i.test(s); }

Prevention

When it happens

Trigger: Supplying a key of any length other than 32 bytes: a 16-byte key, a long passphrase, or a hex/base64 value decoding to != 32 bytes.

Common situations: Reusing a 16-byte AES key or a 64-byte BLAKE2b key as the BLAKE3 key; pasting a passphrase expecting padding; hex miscount.

Related errors


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

Appendix: source

Thrown at src/core/operations/BLAKE3.mjs:59

                "value": ""
            }
        ];
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        const key = args[1];
        const size = args[0];
        const opts = { dkLen: size };
        const inputBytes = new Uint8Array(Utils.strToArrayBuffer(input));
        if (key !== "") {
            const keyBytes = new Uint8Array(Utils.strToArrayBuffer(key));
            if (keyBytes.length !== 32) {
                throw new OperationError("The key must be exactly 32 bytes long");
            }
            opts.key = keyBytes;
        }
        return bytesToHex(blake3(inputBytes, opts));
    }

}

export default BLAKE3;

View on GitHub (pinned to 4290ea7539)