{"record":{"id":"55b5cc4c184a5a83","repo":"CloakHQ/CloakBrowser","slug":"version-mismatch-in-signed-pro-sha256sums-request-55b5cc","errorCode":null,"errorMessage":"Version mismatch in signed Pro SHA256SUMS: requested {version}, manifest declares {declared ?? \"none\"}. Refusing (possible downgrade).","messagePattern":"Version mismatch in signed Pro SHA256SUMS: requested (.+?), manifest declares (.+?)\\. Refusing \\(possible downgrade\\)\\.","errorType":"exception","errorClass":"BinaryVerificationError","httpStatus":null,"severity":"critical","filePath":"dotnet/src/CloakBrowser/Download.cs","lineNumber":617,"sourceCode":"                // InvalidOperationException (the router reports it as \"unavailable,\n                // retry\") rather than a BinaryVerificationError (a tampering signal).\n                throw new InvalidOperationException(\n                    $\"Could not fetch the signed SHA256SUMS for Pro {version} ({exc.Message})\", exc);\n            }\n        }\n\n        var (manifestData, sigData) = manifest.Value;\n\n        // VerifySignature / VerifyChecksum throw InvalidOperationException; convert to\n        // BinaryVerificationError so the Pro router treats them as tampering signals\n        // (re-raise) rather than transient failures (fall back to free).\n        try\n        {\n            VerifySignature(manifestData, sigData);\n        }\n        catch (InvalidOperationException exc)\n        {\n            throw new BinaryVerificationError(exc.Message, exc);\n        }\n\n        var manifestText = System.Text.Encoding.UTF8.GetString(manifestData);\n\n        // Version binding: same forced-downgrade defense as the official free path.\n        var declared = ParseManifestVersion(manifestText);\n        if (declared != version)\n            throw new BinaryVerificationError(\n                $\"Version mismatch in signed Pro SHA256SUMS: requested {version}, \" +\n                $\"manifest declares {declared ?? \"none\"}. Refusing (possible downgrade).\");\n\n        var tarballName = Config.GetArchiveName();\n        var checksums = ParseChecksums(manifestText);\n        if (!checksums.TryGetValue(tarballName, out var expected))\n            throw new BinaryVerificationError(\n                $\"Signature-verified Pro SHA256SUMS has no entry for {tarballName} - \" +\n                \"cannot confirm binary integrity.\");\n        try","sourceCodeStart":599,"sourceCodeEnd":635,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/dotnet/src/CloakBrowser/Download.cs#L599-L635","documentation":"Thrown during Pro binary verification when the version declared inside the signature-verified SHA256SUMS manifest does not match the version the caller requested. The signature only proves who made the manifest, so this check prevents a mirror from serving a genuinely-signed but older release in place of the requested one (forced downgrade).","triggerScenarios":"Calling DownloadProBinaryAsync (which calls VerifyProDownloadAsync) with a version argument that differs from the version string ParseManifestVersion extracts from the fetched SHA256SUMS text, e.g. requesting 1.2.3 while the manifest lists 1.2.2 or has no parseable version.","commonSituations":"Passing an outdated or mistyped version string; a cached/mirrored manifest for a different release; upstream published a manifest whose header names a different version than the tag it was uploaded under.","solutions":["Confirm the exact version string you passed to DownloadProBinaryAsync matches the published release tag (no 'v' prefix vs with prefix mismatches)","Retry with the version omitted so the library resolves the default","Clear any local/cached manifest and retry; if the mismatch persists, report it at the project's issue tracker since upstream's manifest may be mis-published"],"exampleFix":"// before\nvar path = await dl.DownloadProBinaryAsync(\"1.2.2\", ct);\n// after - pass the version the release actually declares\nvar path = await dl.DownloadProBinaryAsync(\"1.2.3\", ct);","handlingStrategy":"validation","validationCode":"var requested = \"1.2.3\";\nvar declared = ParseManifestVersion(manifestText); // expose or replicate\nif (declared != null && declared != requested)\n    throw new InvalidOperationException($\"Refusing: manifest is {declared}, requested {requested}\");\nawait dl.DownloadProBinaryAsync(requested, ct);","typeGuard":null,"tryCatchPattern":"try { await dl.DownloadProBinaryAsync(version, ct); }\ncatch (BinaryVerificationError e) when (e.Message.Contains(\"Version mismatch\"))\n{ /* log version, fail hard - do NOT retry with the declared (older) version */ }","preventionTips":["Always derive the version string from the same source the release publisher uses","Pin your version in one constant and test after upgrades"],"tags":["version-mismatch","integrity","downgrade","pro-download"],"backgroundTag":"version-mismatch","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}