JosefNemec/Playnite · critical · Exception
Failed to download installer file.
Error message
Failed to download installer file.
What it means
Thrown by TryDownloadInstaller after every installer-file URL fails. The loop attempts DownloadFileTaskAsync per URL (writing to App.InstallerDownloadPath), logs WebException and generic exceptions per URL, then throws a plain 'Failed to download installer file.' when none succeed. The actionable detail lives in the per-URL logger.Error lines, not in this message.
Source
Thrown at source/Tools/PlayniteInstaller/MainViewModel.cs:287
}
catch (WebException webExp)
{
if (webExp.Status == WebExceptionStatus.RequestCanceled)
{
return false;
}
else
{
logger.Error(webExp, $"Failed to download installer file from {url}");
}
}
catch (Exception e)
{
logger.Error(e, $"Failed to download installer file from {url}");
}
}
throw new Exception("Failed to download installer file.");
}
private void WebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
ProgressValue = e.ProgressPercentage;
}
public void Cancel()
{
if (Status == InstallStatus.Downloading)
{
webClient.CancelAsync();
webClient.Dispose();
webClient = null;
Status = InstallStatus.Idle;
}
else
{
View on GitHub (pinned to 5911f4e964)
Solutions
- Read the per-URL 'Failed to download installer file from <url>' log entries — they contain the WebException status (ProtocolError, ConnectFailure, etc.).
- Confirm App.InstallerDownloadPath is writable and the volume has free space.
- Retry on a stable network / different network; whitelist the installer CDN host on any proxy.
- If URLs are 404, re-fetch the installer manifest to get current download links, or update Toolbox to a version pointing at valid installer URLs.
Example fix
// before
throw new Exception("Failed to download installer file.");
// after (preserve causes)
throw new AggregateException("Failed to download installer file from any URL.", errors); // where 'errors' collected per-URL exceptions
// and guard the write target beforehand:
var dir = Path.GetDirectoryName(App.InstallerDownloadPath);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); Defensive patterns
Strategy: retry
Validate before calling
var dir = Path.GetDirectoryName(App.InstallerDownloadPath);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
if (!HasWriteAccess(dir)) throw new UnauthorizedAccessException($"Cannot write to {dir}"); Try / catch
Exception lastError = null;
foreach (var url in urls)
{
try { await webClient.DownloadFileTaskAsync(url, App.InstallerDownloadPath); return true; }
catch (Exception e) { logger.Error(e, $"installer file fetch failed: {url}"); lastError = e; }
}
throw new Exception("Failed to download installer file.", lastError); Prevention
- Validate the download path is writable and the disk has space before starting.
- Surface the per-URL WebException (status code) so 404 vs connect-failure vs disk-full is distinguishable.
- Re-fetch the installer manifest if file URLs 404, to pick up corrected download links.
When it happens
Trigger: Manifest download (GetInstallerManifest) succeeded but the actual installer binary URLs all fail: 404 on the file, disk full / permission denied at App.InstallerDownloadPath, network drop mid-download, proxy blocking the CDN, or the installer path moved post-manifest.
Common situations: Disk full or no write permission for the installer download path; CDN/host returns 404 because the build was pulled; partial download then connection reset; proxy stripping Content-Length; antivirus locking the partially written file.
Related errors
- Failed to download installer manifest.
- Failed to download update file.
- Failed to download string from all mirrors.
- Failed to download file from all mirrors.
- Uknown installer manifest url format {InstallerManifestUrl}.
AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13).
Data as JSON: /api/errors/0d6c888348559812.
Report an issue: GitHub.