microsoft/aspire · error · InvalidOperationException

Checksum validation failed. Expected

Error message

Checksum validation failed. Expected: {expectedChecksum}, Actual: {actualChecksum}

What it means

After downloading the CLI archive, the downloader computes the file's SHA-512 hash and compares it against the expected checksum published alongside the download. When the computed hex string differs from the expected value, ValidateChecksumAsync throws InvalidOperationException, treating the downloaded artifact as corrupt or tampered.

Solutions

  1. Retry the download (delete the partially downloaded archive first); transient truncation is the most common cause.
  2. Bypass or disable proxies/SSL inspection for the download URL and try again from a different network if possible.
  3. Check whether a release was just published (checksum and binary temporarily out of sync) and retry later or pin a previous CLI version.
  4. Verify your disk/AV setup if the mismatch reproduces consistently on the same machine.

Example fix

// before
await cliDownloader.DownloadLatestCliAsync(installDir);
// after
try
{
    await cliDownloader.DownloadLatestCliAsync(installDir);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Checksum validation failed"))
{
    Console.Error.WriteLine($"Download integrity check failed: {ex.Message}. Retrying...");
    await cliDownloader.DownloadLatestCliAsync(installDir);
}
Defensive patterns

Strategy: retry

Validate before calling

long len = new FileInfo(archivePath).Length;
if (len == 0 || len < expectedMinSize) throw new IOException("Downloaded archive looks truncated; refusing checksum check.");

Try / catch

try { await DownloadLatestCliAsync(dir); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Checksum validation failed")) { // delete archive, retry with backoff
File.Delete(archivePath); await Task.Delay(2000); await DownloadLatestCliAsync(dir); }

Prevention

When it happens

Trigger: CliDownloader.DownloadLatestCliAsync downloads an archive whose SHA-512 hash does not match the expected checksum fetched from the release metadata - corrupted download, truncated file, CDN/proxy content mutation, or checksum-published-version mismatch.

Common situations: Flaky corporate proxies or SSL-inspecting firewalls rewriting responses, interrupted downloads (partial file), fetching a newer CLI binary than the checksum file describes (race during release publication), or antivirus software modifying the archive on disk.

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 microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/2ff3ab667cef4184. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Cli/Utils/CliDownloader.cs:217

        using var response = await s_httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cts.Token);
        response.EnsureSuccessStatusCode();

        await using var fileStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write, FileShare.None);
        await response.Content.CopyToAsync(fileStream, cts.Token);
    }

    private static async Task ValidateChecksumAsync(string archivePath, string checksumPath, CancellationToken cancellationToken)
    {
        var expectedChecksum = (await File.ReadAllTextAsync(checksumPath, cancellationToken)).Trim().ToLowerInvariant();

        using var sha512 = SHA512.Create();
        await using var fileStream = new FileStream(archivePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        var hashBytes = await sha512.ComputeHashAsync(fileStream, cancellationToken);
        var actualChecksum = Convert.ToHexString(hashBytes).ToLowerInvariant();

        if (expectedChecksum != actualChecksum)
        {
            throw new InvalidOperationException($"Checksum validation failed. Expected: {expectedChecksum}, Actual: {actualChecksum}");
        }
    }
}

View on GitHub (pinned to 25830f84bd)