{"record":{"id":"98e21c6b60c02fff","repo":"siyuan-note/siyuan","slug":"get-checksum-manifest-failed-d","errorCode":null,"errorMessage":"get checksum manifest failed: %d","messagePattern":"get checksum manifest failed: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/updater_release.go","lineNumber":392,"sourceCode":"\t\tcached, ok := githubManifestCache.Load(manifestCacheKey)\n\t\tif ok {\n\t\t\tif checksum := parseChecksumManifest(cached.(string), pkgName); \"\" != checksum {\n\t\t\t\treturn checksum, nil\n\t\t\t}\n\t\t\treturn \"\", errors.New(\"package checksum is unavailable\")\n\t\t}\n\t}\n\n\tresponse, err := httpclient.NewCloudRequest30s().SetContext(ctx).Get(manifestAsset.BrowserDownloadURL)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif nil == response || nil == response.Response {\n\t\treturn \"\", errors.New(\"checksum manifest response is empty\")\n\t}\n\tdefer response.Body.Close()\n\tif 200 != response.StatusCode {\n\t\treturn \"\", fmt.Errorf(\"get checksum manifest failed: %d\", response.StatusCode)\n\t}\n\tdata, err := io.ReadAll(io.LimitReader(response.Body, maxChecksumManifestSize+1))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif maxChecksumManifestSize < int64(len(data)) {\n\t\treturn \"\", errors.New(\"checksum manifest is too large\")\n\t}\n\tif \"\" != manifestDigest {\n\t\tactualDigest := fmt.Sprintf(\"%x\", sha256.Sum256(data))\n\t\tif manifestDigest != actualDigest {\n\t\t\treturn \"\", errors.New(\"checksum manifest digest mismatch\")\n\t\t}\n\t}\n\tmanifest := string(data)\n\tif \"\" != manifestCacheKey {\n\t\tgithubManifestCache.Store(manifestCacheKey, manifest)\n\t}","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/updater_release.go#L374-L410","documentation":"The checksum manifest download completed but GitHub responded with a non-200 status code. The function formats the status into this error and aborts, since only HTTP 200 yields a trustworthy manifest body. No manifest is cached on this path.","triggerScenarios":"GET of manifestAsset.BrowserDownloadURL returns 404 (asset removed), 403 (rate limit/blocked), 302 that terminates in an error page, or 5xx from GitHub/CDN during getGitHubUpdateRelease.","commonSituations":"Anonymous GitHub rate limiting (403 with rate-limit headers); the release was deleted or its assets removed after the API listing was cached; CDN outages; corporate proxies returning block pages.","solutions":["Check the printed status code: 403 usually means GitHub rate limiting — wait for the window to reset or set a token","404 means the manifest asset is gone — verify the release still lists SHA256SUMS.txt","Retry later for 5xx/CDN errors","Bypass misbehaving proxies for github.com if a corporate proxy is intercepting requests"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-check the asset URL reachability\nresp, err := http.Head(manifestURL)\nif err == nil && resp.StatusCode != 200 {\n    logging.LogWarnf(\"manifest URL head status %d; expect failure\", resp.StatusCode)\n}","typeGuard":null,"tryCatchPattern":"checksum, err := getGitHubManifestChecksum(ctx, release, pkgName)\nif err != nil {\n    var statusErr *fmt.Errorf\n    if errors.As(err, &statusErr) && strings.Contains(err.Error(), \"get checksum manifest failed\") {\n        // inspect embedded status: 403 rate limit -> backoff; 404 -> release assets changed\n        return err\n    }\n}","preventionTips":["Respect GitHub rate limits; add a token or slow down update checks","Re-fetch release metadata instead of relying on stale cached listings","Bypass content-filtering proxies for api.github.com and github.com downloads"],"tags":["http","github","network"],"backgroundTag":"http-non-200-response","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}