JosefNemec/Playnite · error · Exception

Failed to download string from all mirrors.

Error message

Failed to download string from all mirrors.

What it means

Thrown by Downloader.DownloadString(IEnumerable<string> mirrors) when every mirror URL in the list raised an exception (each mirror's DownloadString attempt is caught and logged). It is a bare Exception with no inner exception aggregating the per-mirror failures.

Source

Thrown at source/Playnite/Common/Web/Downloader.cs:79

        {
        }

        public string DownloadString(IEnumerable<string> mirrors)
        {
            logger.Debug($"Downloading string content from multiple mirrors.");
            foreach (var mirror in mirrors)
            {
                try
                {
                    return DownloadString(mirror);
                }
                catch (Exception e)
                {
                    logger.Error(e, $"Failed to download {mirror} string.");
                }
            }

            throw new Exception("Failed to download string from all mirrors.");
        }

        public string DownloadString(string url)
        {
            return DownloadString(url, Encoding.UTF8);
        }

        public string DownloadString(string url, CancellationToken cancelToken)
        {
            logger.Debug($"Downloading string content from {url} using UTF8 encoding.");

            try
            {
                using (var webClient = new CustomWebClient { Encoding = Encoding.UTF8 })
                using (var registration = cancelToken.Register(() => webClient.CancelAsync()))
                {
                    webClient.Headers.Add("User-Agent", playniteUserAgent);
                    return Task.Run(async () => await webClient.DownloadStringTaskAsync(url)).GetAwaiter().GetResult();

View on GitHub (pinned to 5911f4e964)

Solutions

  1. Check connectivity and that at least one mirror URL is reachable in a browser.
  2. Review the logged per-mirror errors (logger.Error above the throw) for the real cause.
  3. Verify the mirrors list is non-empty and the URLs are correct.
  4. Configure the proxy/cert chain or retry when the network recovers.

Example fix

// before
var s = downloader.DownloadString(mirrors);

// after — guard empty list and capture per-mirror failures
if (mirrors == null || !mirrors.Any()) throw new InvalidOperationException("No mirrors configured.");
List<Exception> failures = new List<Exception>();
foreach (var m in mirrors)
{
    try { return downloader.DownloadString(m); }
    catch (Exception e) { failures.Add(e); }
}
throw new AggregateException("All mirrors failed", failures);
Defensive patterns

Strategy: retry

Validate before calling

if (mirrors == null || !mirrors.Any()) throw new InvalidOperationException("No mirrors configured.");

Type guard

static bool HasMirrors(IEnumerable<string> m) => m != null && m.Any(s => !s.IsNullOrWhiteSpace());

Try / catch

try { return downloader.DownloadString(mirrors); }
catch (Exception ex) { logger.Error(ex, "download string failed"); /* optional: retry with a single primary mirror */ return null; }

Prevention

When it happens

Trigger: All mirrors are unreachable (offline, DNS failure, 4xx/5xx, TLS error, timeout); mirrors list is empty so the loop body never runs and it throws immediately; network proxy blocking all hosts.

Common situations: Fetching update/metadata strings during an outage or behind a captive portal; mirror URLs misconfigured; corporate firewall/proxy rejecting the hosts; expired TLS cert on all mirrors.

Related errors


AI-assisted analysis of JosefNemec/Playnite@5911f4e964 (2026-08-13). Data as JSON: /api/errors/b751a8dc8ca9ac5a. Report an issue: GitHub.