beeradmoore/dlss-swapper · error · Exception
Downloaded file was invalid.
Error message
Downloaded file was invalid.
What it means
After a successful download, DownloadAsync computes the MD5 of the downloaded zip and compares it to the record's expected ZipMD5Hash from the manifest; a mismatch throws this error because the package cannot be trusted/verified. The library never extracts an archive that fails hash verification.
Solutions
- Retry the download to rule out transient corruption
- Verify the file's MD5 manually against the upstream release and update ZipMD5Hash in the manifest
- Update the app/manifest to the latest version with corrected hashes
- Check proxy/AV interference if corruption reproduces consistently
Example fix
// before
if (ZipMD5Hash != fileStream.GetMD5Hash())
{
throw new Exception("Downloaded file was invalid.");
}
// after
var actualHash = fileStream.GetMD5Hash();
if (!string.Equals(ZipMD5Hash, actualHash, StringComparison.OrdinalIgnoreCase))
{
throw new Exception($"Downloaded file MD5 '{actualHash}' did not match expected '{ZipMD5Hash}'.");
} Defensive patterns
Strategy: retry
Validate before calling
// after download, verify before the library does
fileStream.Position = 0;
var hash = fileStream.GetMD5Hash();
if (!string.Equals(hash, expectedZipMd5, StringComparison.OrdinalIgnoreCase))
File.Delete(tempZipFile); // force clean re-download Try / catch
try
{
await dllRecord.DownloadAsync();
}
catch (Exception ex) when (ex.Message == "Downloaded file was invalid.")
{
File.Delete(tempZipPath);
await dllRecord.DownloadAsync(); // retry once; if it recurs, the manifest hash is stale
} Prevention
- Retry once on hash mismatch to rule out transient corruption
- Update manifest hashes whenever upstream republishes packages
- Check proxy/AV tools that alter downloaded content
- Compare downloaded size against Content-Length before hashing
When it happens
Trigger: Downloaded zip's MD5 differs from DLLRecord.ZipMD5Hash — upstream replaced the file without updating the manifest hash, the download was truncated/corrupted in transit, a proxy/AV modified the body, or the manifest pins a stale hash.
Common situations: New upstream release published while manifest still lists the old hash; flaky connection dropping bytes; corporate proxy or antivirus re-compressing/altering downloads; manifest updated with hash of a differently-encoded file.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15).
Data as JSON: /api/errors/66d39c36eacaa0df.
Report an issue: GitHub.
Appendix: source
Thrown at src/Data/DLLRecord.cs:300
try
{
LocalRecord.FileDownloader = fileDownloader;
NotifyPropertyChanged(nameof(LocalRecord));
using (var fileStream = new FileStream(tempZipFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None, FileDownloader.BufferSize, true))
{
var didDownload = await LocalRecord.FileDownloader.DownloadFileToStreamAsync(fileStream, cancellationToken).ConfigureAwait(false);
if (didDownload == false)
{
throw new Exception("Could not download file.");
}
if (ZipMD5Hash != fileStream.GetMD5Hash())
{
throw new Exception("Downloaded file was invalid.");
}
fileStream.Position = 0;
using (var zipArchive = new ZipArchive(fileStream, ZipArchiveMode.Read, true))
{
DLLManager.HandleExtractFromZip(zipArchive, this);
}
}
App.CurrentApp.RunOnUIThread(() =>
{
LocalRecord.IsDownloaded = true;
NotifyPropertyChanged(nameof(LocalRecord));
});
return (true, string.Empty, false);
}View on GitHub (pinned to ab9b1e2d4b)