nilaoda/N_m3u8DL-RE · error · ArgumentException

must be valid 16-byte HEX or Base64. Input string

Error message

{label} must be valid 16-byte HEX or Base64. Input string: {part}

What it means

When parsing decryption key options, each KEY/KID:KEY part must be either a 32-char hex string (16 bytes) or a Base64 string that decodes to exactly 16 bytes. ParsePart lowercases the normalized hex and throws ArgumentException if the part matches neither form, naming the label (KEY or KID) and echoing the offending input.

Solutions

  1. Provide the key as 32 hex characters (16 bytes), e.g. "d1f2..." without 0x prefix.
  2. Or provide valid Base64 whose decoded length is exactly 16 bytes.
  3. Strip whitespace, quotes and '0x' prefixes from the pasted value.
  4. For non-16-byte keys, confirm the stream actually uses 128-bit keys; longer keys are unsupported here.

Example fix

// before
--key "0xD1F2E3..." // 0x prefix, wrong length
// after
--key "d1f2e3c4b5a697887766554433221100" // 32 hex chars
Defensive patterns

Strategy: validation

Validate before calling

bool ValidKeyPart(string p) =>
    System.Text.RegularExpressions.Regex.IsMatch(p, "^[0-9a-fA-F]{32}$") ||
    (TryConvert.FromBase64String(p) is var b && b != null && b.Length == 16);

Type guard

bool Is16ByteHexOrB64(string s) => s.Length == 32 && s.All(Uri.IsHexCharacter ?? (char c => Uri.IsHexDigit(c))) || TryBase6416(s);

Try / catch

try { ParseKeyOption(tokens); }
catch (ArgumentException ex) { Console.Error.WriteLine(ex.Message); return 1; }

Prevention

When it happens

Trigger: Passing a --key value that is a 24-byte/32-byte key, a hex string with odd length or non-hex characters, a Base64 string decoding to a length other than 16, or a raw passphrase.

Common situations: Users paste full 32-byte AES-256 keys, include a '0x' prefix, copy a KID+KEY with surrounding whitespace/extra characters, or supply a key from a non-Standard (non-16-byte) DRM scheme.

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/456d6d96b51434b1. Report an issue: GitHub.

Appendix: source

Thrown at src/N_m3u8DL-RE/CommandLine/CommandInvoker.cs:245

    /// - KEY(hex)<br/>
    /// - KID:KEY(hex)<br/>
    /// - Base64KEY<br/>
    /// - Base64KID:Base64KEY
    /// </summary>
    private static string[]? ParseCustomKeys(ArgumentResult result)
    {
        const int KeyBytes = 16;
        const int KeyHexLen = KeyBytes * 2;
        
        string ParsePart(string part, string label)
        {
            if (SingleHexKeyRegex().IsMatch(part))
                return part.ToLowerInvariant();

            if (HexUtil.TryParseBase64(part, out var hex) && hex is { Length: KeyHexLen })
                return hex.ToLowerInvariant();

            throw new ArgumentException($"{label} must be valid 16-byte HEX or Base64. Input string: {part}");
        }

        var keys = new List<string>();
        var inputs = result.Tokens.Select(t => t.Value).ToList();

        try
        {
            foreach (var input in inputs)
            {
                // 已匹配标准格式的,直接添加
                if (PairKeyRegex().IsMatch(input) || IdHexKeyRegex().IsMatch(input) || SingleHexKeyRegex().IsMatch(input))
                {
                    keys.Add(input);
                    continue;
                }

                // 拆分KID:KEY
                var parts = input.Split(':', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

View on GitHub (pinned to e113dee70c)