nilaoda/N_m3u8DL-RE · error · ArgumentException

Key length must be . Actual

Error message

Key length must be {allowedKeyLength}. Actual: {key.Length}

What it means

CSChaCha20 only accepts a 256-bit key. KeySetup compares key.Length against allowedKeyLength (32) and throws ArgumentException("Key length must be 32. Actual: N") on any other size, because the state initialization reads exactly 32 bytes in 8 little-endian words.

Solutions

  1. Ensure the key is exactly 32 bytes (64 hex chars) before constructing the cipher.
  2. Trim whitespace/newlines from decoded key material.
  3. If the source key is 16 bytes, confirm the encryption actually uses ChaCha20-256; otherwise use the matching cipher.
  4. Add an upfront length assertion where keys are parsed.

Example fix

// before
var key = Convert.FromHexString(hexKey); // may be 16 bytes
// after
if (key.Length != 32) Array.Resize(ref key, 32); // better: validate & reject
var cipher = new CSChaCha20(key, nonce, 0);
Defensive patterns

Strategy: validation

Validate before calling

if (keyBytes == null || keyBytes.Length != 32) throw new InvalidOperationException($"ChaCha20 key must be 32 bytes, got {keyBytes?.Length ?? 0}");

Type guard

bool IsChaCha20Key(byte[] k) => k is { Length: 32 };

Try / catch

try { cipher = new CSChaCha20(key, nonce, 0); }
catch (ArgumentException ex) { Console.Error.WriteLine($"Bad key: {ex.Message}"); }

Prevention

When it happens

Trigger: Passing a 16-byte (AES-128) key, a hex string decoded to the wrong byte count, or a key buffer with a length prefix/BOM included to the ChaCha20 constructor.

Common situations: Users supply 16-byte SAMPLE-AES keys meant for AES-CTR; Base64/hex decode helpers produce padded or truncated buffers; key material read from a file includes trailing newline bytes.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of nilaoda/N_m3u8DL-RE@e113dee70c (2026-09-13). Data as JSON: /api/errors/45d7934a87c13321. Report an issue: GitHub.

Appendix: source

Thrown at src/N_m3u8DL-RE/Crypto/CSChaCha20.cs:130

        private static readonly byte[] sigma = Encoding.ASCII.GetBytes("expand 32-byte k");
        private static readonly byte[] tau = Encoding.ASCII.GetBytes("expand 16-byte k");

        /// <summary>
        /// Set up the ChaCha state with the given key. A 32-byte key is required and enforced.
        /// </summary>
        /// <param name="key">
        /// A 32-byte (256-bit) key, treated as a concatenation of eight 32-bit little-endian integers
        /// </param>
        private void KeySetup(byte[] key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("Key is null");
            }

            if (key.Length != allowedKeyLength)
            {
                throw new ArgumentException($"Key length must be {allowedKeyLength}. Actual: {key.Length}");
            }

            state[4] = Util.U8To32Little(key, 0);
            state[5] = Util.U8To32Little(key, 4);
            state[6] = Util.U8To32Little(key, 8);
            state[7] = Util.U8To32Little(key, 12);

            byte[] constants = (key.Length == allowedKeyLength) ? sigma : tau;
            int keyIndex = key.Length - 16;

            state[8] = Util.U8To32Little(key, keyIndex + 0);
            state[9] = Util.U8To32Little(key, keyIndex + 4);
            state[10] = Util.U8To32Little(key, keyIndex + 8);
            state[11] = Util.U8To32Little(key, keyIndex + 12);

            state[0] = Util.U8To32Little(constants, 0);
            state[1] = Util.U8To32Little(constants, 4);
            state[2] = Util.U8To32Little(constants, 8);

View on GitHub (pinned to e113dee70c)