SubtitleEdit/subtitleedit · error · IOException

llama.cpp {label} download failed integrity check (expected

Error message

llama.cpp {label} download failed integrity check (expected SHA-256 {expected}, got {actual}).

What it means

Thrown by LlamaCppDownloadService's integrity check. The expected hash is fetched from DownloadHashManager.GetLatestKnownHash(key); an empty/null value skips verification. When set, the SHA-256 of the stream is compared case-insensitively, and a mismatch raises IOException so the pipeline treats it as an I/O fault. The stream is rewound to Position 0 before and after hashing so downstream use continues from the start.

Source

Thrown at src/ui/Logic/Download/LlamaCppDownloadService.cs:65

    {
        if (string.IsNullOrEmpty(key) || stream.Length == 0)
        {
            return;
        }

        var expected = DownloadHashManager.GetLatestKnownHash(key);
        if (string.IsNullOrEmpty(expected))
        {
            return;
        }

        stream.Position = 0;
        var actual = await Sha256Util.ComputeSha256Async(stream, cancellationToken);
        stream.Position = 0;

        if (!string.Equals(expected, actual, StringComparison.OrdinalIgnoreCase))
        {
            throw new IOException(
                $"llama.cpp {label} download failed integrity check (expected SHA-256 {expected}, got {actual}).");
        }
    }

    public async Task DownloadCudaRuntime(Stream stream, string variant, IProgress<float>? progress, CancellationToken cancellationToken)
    {
        // The two CUDA builds need different redistributables (cudart64_12.dll vs cudart64_13.dll),
        // so the runtime archive has to follow whichever engine variant was picked.
        var isCuda13 = variant == VariantCuda13;
        var url = BaseUrl + (isCuda13 ? "cudart-llama-bin-win-cuda-13.3-x64.zip" : "cudart-llama-bin-win-cuda-12.4-x64.zip");
        var key = isCuda13 ? DownloadHashManager.LlamaCpp.WindowsCuda13Runtime : DownloadHashManager.LlamaCpp.WindowsCudaRuntime;

        await DownloadHelper.DownloadFileAsync(httpClient, url, stream, progress, cancellationToken);
        await VerifyArchive(stream, key, "CUDA runtime", cancellationToken);
    }

    public async Task DownloadModel(string url, string destinationFileName, IProgress<float>? progress, CancellationToken cancellationToken)
    {

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Clear the cached llama.cpp download so the service re-fetches bytes matching the manager's current hash.
  2. Verify DownloadHashManager.GetLatestKnownHash(key) corresponds to the artifact upstream is currently serving; correct the manager if a rolling update mis-fired.
  3. Re-download via a clean network path / alternate mirror to rule out corruption in transit.
  4. Confirm no AV/sync process modifies the file while it is being hashed.

Example fix

// before
await llamaService.DownloadEngine(stream, variant, progress, ct);

// after: force fresh download to match rolling hash
stream.SetLength(0);
await llamaService.DownloadEngine(stream, variant, progress, ct);
Defensive patterns

Strategy: try-catch

Validate before calling

var expected = DownloadHashManager.GetLatestKnownHash(key);
if (string.IsNullOrEmpty(expected)) { /* verification skipped */ }

Try / catch

try { await llamaService.VerifyAsync(stream, label, key, ct); }
catch (IOException ex) when (ex.Message.Contains("failed integrity check"))
{ stream.SetLength(0); await llamaService.DownloadEngine(stream, variant, progress, ct); }

Prevention

When it happens

Trigger: A non-empty known hash exists for the llama.cpp download key, and the actual SHA-256 of the stream differs: corrupt/truncated download, wrong artifact served by mirror, MITM/proxy alteration, or the manager's rolling hash advanced to a new build while the cached bytes are from the old one.

Common situations: Rolling hash update in DownloadHashManager after a new llama.cpp release, but local cache still holds the prior binary; partial download flagged success; AV/quarantine altered bytes; CDN edge served stale artifact.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/91a76ed1fb96ee0b. Report an issue: GitHub.