SubtitleEdit/subtitleedit · error · IOException

VoxCPM2 (CrispASR) model {fileName} failed integrity check (

Error message

VoxCPM2 (CrispASR) model {fileName} failed integrity check (expected SHA-256 {expected}, got {actual}).

What it means

Integrity check for the VoxCPM2 CrispASR model set, structurally identical to the other CrispASR services. File is opened read-only, hashed, compared case-insensitively to the pinned expected hash; mismatch throws IOException.

Source

Thrown at src/ui/Logic/Download/VoxCPM2CrispAsrDownloadService.cs:136

        {
            return;
        }

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

        string actual;
        await using (var stream = File.OpenRead(filePath))
        {
            actual = await Sha256Util.ComputeSha256Async(stream, cancellationToken);
        }

        if (!string.Equals(expected, actual, StringComparison.OrdinalIgnoreCase))
        {
            throw new IOException(
                $"VoxCPM2 (CrispASR) model {fileName} failed integrity check (expected SHA-256 {expected}, got {actual}).");
        }
    }

    private static string GetUrl(string fileName)
    {
        if (!ModelUrls.TryGetValue(fileName, out var url))
        {
            throw new ArgumentException($"Unknown VoxCPM2 (CrispASR) model: {fileName}", nameof(fileName));
        }
        return url;
    }

    private static void TryDelete(string path)
    {
        try { File.Delete(path); } catch { /* best-effort cleanup */ }
    }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Delete the cached model file and re-download.
  2. Confirm the pinned expected hash matches the current origin artifact.
  3. Check network/disk for truncation.
  4. If the model was intentionally republished, update the hash constant in VoxCPM2CrispAsrDownloadService.
Defensive patterns

Strategy: try-catch

Validate before calling

var cached = Path.Combine(modelFolder, fileName);
if (File.Exists(cached))
{
    using var s = File.OpenRead(cached);
    var h = await Sha256Util.ComputeSha256Async(s, ct);
    if (!string.Equals(expected, h, StringComparison.OrdinalIgnoreCase)) File.Delete(cached);
}

Try / catch

try { await service.DownloadModelAsync(...); }
catch (IOException ex) when (ex.Message.Contains("failed integrity check"))
{
    if (File.Exists(filePath)) File.Delete(filePath);
    await service.DownloadModelAsync(...);
}

Prevention

When it happens

Trigger: Non-empty expected hash that differs from the computed SHA-256 of filePath. Empty expected short-circuits.

Common situations: Truncated download, CDN artifact swap without hash bump, corrupt local cache, or stale cache after a binary update.

Related errors


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