{"record":{"id":"7c8ab95bc16e023a","repo":"microsoft/aspire","slug":"aspire-skills-github-release-asset-0-failed-sha-256","errorCode":null,"errorMessage":"Aspire skills GitHub release asset '{0}' failed SHA-256 verification.","messagePattern":"Aspire skills GitHub release asset '(.+?)' failed SHA-256 verification\\.","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Agents/AspireSkills/AspireSkillsInstaller.cs","lineNumber":222,"sourceCode":"                {\n                    return cachedResult;\n                }\n            }\n\n            var archivePath = Path.Combine(tempDirectory.FullName, GetSafeFileName(asset.Name));\n            if (!await TryDownloadGitHubAssetAsync(httpClient, asset.DownloadUrl, archivePath, cancellationToken).ConfigureAwait(false))\n            {\n                logger.LogDebug(\"Aspire skills GitHub release asset {AssetName} was unavailable for version {Version}.\", asset.Name, version);\n                return AcquisitionResult.Unavailable(knownGitHubArchiveSha256, githubReleaseMetadataAvailable);\n            }\n\n            try\n            {\n                var githubArchiveSha256 = ComputeArchiveSha256(archivePath);\n                if (knownGitHubArchiveSha256 is not null &&\n                    !string.Equals(githubArchiveSha256, knownGitHubArchiveSha256, StringComparison.OrdinalIgnoreCase))\n                {\n                    throw new InvalidDataException(string.Format(\n                        CultureInfo.InvariantCulture,\n                        \"Aspire skills GitHub release asset '{0}' failed SHA-256 verification.\",\n                        asset.Name));\n                }\n\n                if (!validationDisabled)\n                {\n                    var provenanceResult = await githubArtifactAttestationVerifier.VerifyAsync(\n                        GitHubRepository,\n                        archivePath,\n                        ExpectedSourceRepository,\n                        ExpectedWorkflowPath,\n                        ExpectedBuildType,\n                        version,\n                        cancellationToken).ConfigureAwait(false);\n\n                    if (!provenanceResult.IsVerified)\n                    {","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Agents/AspireSkills/AspireSkillsInstaller.cs#L204-L240","documentation":"When installing a skills bundle from a GitHub release, InstallFromGitHubAsync computes the SHA-256 of the downloaded archive and, if the release metadata supplied an expected hash, compares them. A mismatch throws InvalidDataException naming the asset, guarding against corrupted or tampered downloads.","triggerScenarios":"Downloaded archive's computed SHA-256 differs from knownGitHubArchiveSha256 (the expected digest from the release/checksum data); thrown in InstallFromGitHubAsync called from InstallCoreAsync.","commonSituations":"Partial/corrupted download, CDN or proxy altering the bytes, a release asset republished with different contents but a stale checksum, or a compromised asset (the scenario the check exists for).","solutions":["Re-download the asset and retry the install (transient corruption is the most common cause)","Check whether the release was republished; if so, the expected checksum may be stale — use an updated bundle release","Verify the expected SHA-256 published by the release matches the manifest/checksum source, and report the mismatch if the asset was tampered with"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify the archive digest before handing it to the installer\nusing var sha = System.Security.Cryptography.SHA256.Create();\nvar hash = Convert.ToHexString(sha.ComputeHash(File.ReadAllBytes(archivePath)));\nbool matches = string.Equals(hash, expectedSha256, StringComparison.OrdinalIgnoreCase);","typeGuard":null,"tryCatchPattern":"try\n{\n    await installer.InstallFromGitHubAsync(release, ct);\n}\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"failed SHA-256 verification\"))\n{\n    logger.LogError(ex, \"Archive failed SHA-256 verification; re-download or do not trust this release asset.\");\n    // treat as untrusted input: delete the cached archive\n    File.Delete(archivePath);\n}","preventionTips":["Prefer secure, retryable downloads so a corrupted file is re-fetched automatically","Keep checksum data in the release metadata in sync when republishing assets","Never bypass the checksum check for untrusted sources","Delete and re-download the archive when verification fails rather than reusing it"],"tags":["cli","skills-bundle","sha256","checksum","security"],"backgroundTag":"checksum-mismatch","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}