router-for-me/CLIProxyAPI · critical
artifact checksum mismatch
Error message
artifact checksum mismatch
What it means
VerifyArtifactChecksum computes sha256 over the downloaded bytes and compares it (lower-cased, trimmed) to artifact.SHA256. 'artifact checksum mismatch' means the content served by the URL differs from the digest declared in the manifest. It is the direct-download integrity gate, analogous to error 600 but keyed on the artifact entry rather than a checksums map.
Source
Thrown at internal/pluginstore/direct.go:53
data, errDownload := c.get(ctx, artifact.URL, "application/octet-stream", RequestKindArtifact, maxSize)
if errDownload != nil {
return nil, errDownload
}
if maxSize > 0 && int64(len(data)) > maxSize {
return nil, fmt.Errorf("artifact exceeds declared size")
}
return data, nil
}
func VerifyArtifactChecksum(artifact Artifact, data []byte) error {
expected := strings.ToLower(strings.TrimSpace(artifact.SHA256))
if expected == "" {
return fmt.Errorf("artifact checksum missing")
}
actualBytes := sha256.Sum256(data)
actual := hex.EncodeToString(actualBytes[:])
if actual != expected {
return fmt.Errorf("artifact checksum mismatch")
}
return nil
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Re-download once to rule out transport corruption, then verify manually with sha256sum.
- Update the manifest's sha256 to the digest of the currently served binary (or republish the correct old binary).
- Pin artifact URLs to immutable, versioned release assets instead of mutable 'latest' links.
- Automate manifest regeneration in CI so sha256/size are recomputed on every release.
Example fix
// before // manifest built from v1.2.3, URL later repointed to v1.3.0 binary data, _ := client.DownloadArtifact(ctx, artifact) err := pluginstore.VerifyArtifactChecksum(artifact, data) // mismatch // after // version the URL and regenerate digest on release: // url: https://example.com/p/1.3.0/p-linux-amd64 // sha256: <digest of the 1.3.0 binary> data, _ := client.DownloadArtifact(ctx, artifact) err := pluginstore.VerifyArtifactChecksum(artifact, data)
Defensive patterns
Strategy: try-catch
Validate before calling
if strings.TrimSpace(artifact.SHA256) == "" {
return errors.New("cannot pre-verify: manifest sha256 missing")
} Try / catch
if err := pluginstore.VerifyArtifactChecksum(artifact, data); err != nil {
if strings.Contains(err.Error(), "checksum mismatch") {
// one retry with cache-bypass, then abort; never install unverified bytes
return fmt.Errorf("integrity failure for %s: %w", artifact.Name, err)
}
return err
} Prevention
- Pin versioned artifact URLs, never mutable 'latest' links.
- Automate digest regeneration per release; verify with sha256sum when diagnosing.
When it happens
Trigger: DownloadArtifact output passed to VerifyArtifactChecksum where the digest differs: republished/rebuilt binary with a stale manifest sha256, corrupted or truncated download, or a redirect serving different content (e.g. a 'latest' URL that moved to a new build).
Common situations: Release pipeline rebuilt binaries but the plugin manifest was not regenerated; using mutable URLs (latest, /stable) instead of versioned artifact URLs; a mirror or proxy tampering with content.
Related errors
- checksum mismatch for %s
- line %d: invalid checksum entry
- line %d: invalid sha256 length
- checksum for %s not found
- artifact checksum missing
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/ab8e5732a5f240da.
Report an issue: GitHub.