nilaoda/N_m3u8DL-RE · error · FileNotFoundException
{DecryptionBinaryPath}
Error message
{DecryptionBinaryPath} What it means
DoWorkAsync validates that a user-supplied decryption binary (--decryption-binary-path) actually exists on disk when keys are provided. The thrown FileNotFoundException's message is the path itself, so the error text is the missing file path.
Solutions
- Correct --decryption-binary-path to the full absolute path of the binary
- Verify the file exists: ls <path> / dir <path>
- Reinstall mp4decrypt (from Bento4) or shaka-packager and use the new path
- Run from a working directory where the relative path resolves, or switch to an absolute path
Example fix
// before --decryption-binary-path mp4decrypt // after --decryption-binary-path /usr/local/bin/mp4decrypt
Defensive patterns
Strategy: validation
Validate before calling
if (!string.IsNullOrEmpty(decryptionBinaryPath) && !File.Exists(decryptionBinaryPath))
throw new FileNotFoundException($"decryption binary missing: {decryptionBinaryPath}"); Type guard
static bool DecryptionBinaryValid(CLIOptions o) => string.IsNullOrEmpty(o.DecryptionBinaryPath) || File.Exists(o.DecryptionBinaryPath);
Try / catch
try { await DoWorkAsync(option); }
catch (FileNotFoundException ex) when (ex.FileName == null && ex.Message.Contains("decrypt") || ex.Message.EndsWith(".exe"))
{
Console.Error.WriteLine($"decryption binary not found: {ex.Message}");
} Prevention
- Always use absolute paths for --decryption-binary-path
- Re-check paths after upgrading Bento4/shaka-packager
- Note the thrown message is the raw path — use it to identify which file was missing
When it happens
Trigger: option.DecryptionBinaryPath is set (e.g. via --decryption-binary-path) and non-empty, but File.Exists returns false, while option.Keys or --key-text-file indicates decryption will be needed.
Common situations: Typo in the path to mp4decrypt/shaka-packager; binary moved after an upgrade; relative path resolved from a different working directory; Windows users quoting the path incorrectly.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- must be valid 16-byte HEX or Base64. Input string
- Input must be KEY or KID:KEY format.
- MuxAfterDone disabled, MuxImports not allowed!
- ResString.shakaPackagerNotFound
- Invalid Speed Limit
AI-assisted analysis of nilaoda/N_m3u8DL-RE@e113dee70c (2026-09-13).
Data as JSON: /api/errors/f336442aa0b6ba6e.
Report an issue: GitHub.
Appendix: source
Thrown at src/N_m3u8DL-RE/Program.cs:156
Logger.Extra($"ffmpeg => {option.FFmpegBinaryPath}");
// 预先检查mkvmerge
if (option is { MuxOptions.UseMkvmerge: true, MuxAfterDone: true })
{
option.MkvmergeBinaryPath ??= GlobalUtil.FindExecutable("mkvmerge");
if (string.IsNullOrEmpty(option.MkvmergeBinaryPath) || !File.Exists(option.MkvmergeBinaryPath))
{
throw new FileNotFoundException(ResString.mkvmergeNotFound);
}
Logger.Extra($"mkvmerge => {option.MkvmergeBinaryPath}");
}
// 预先检查
if (option.Keys is { Length: > 0 } || option.KeyTextFile != null)
{
if (!string.IsNullOrEmpty(option.DecryptionBinaryPath) && !File.Exists(option.DecryptionBinaryPath))
{
throw new FileNotFoundException(option.DecryptionBinaryPath);
}
switch (option.DecryptionEngine)
{
case DecryptEngine.SHAKA_PACKAGER:
{
var file = FindShakaPackager();
if (file == null) throw new FileNotFoundException(ResString.shakaPackagerNotFound);
option.DecryptionBinaryPath = file;
Logger.Extra($"shaka-packager => {option.DecryptionBinaryPath}");
break;
}
case DecryptEngine.MP4DECRYPT:
{
var file = GlobalUtil.FindExecutable("mp4decrypt");
if (file == null) throw new FileNotFoundException(ResString.mp4decryptNotFound);
option.DecryptionBinaryPath = file;
Logger.Extra($"mp4decrypt => {option.DecryptionBinaryPath}");
break;View on GitHub (pinned to e113dee70c)