MHSanaei/3x-ui · critical
Xray update aborted: the downloaded archive does not match t
Error message
Xray update aborted: the downloaded archive does not match the official SHA-256 checksum, so the image is corrupted or differs from the official release. Please exit and re-download the official image, then try again (expected %s, got %s)
What it means
Returned by downloadXRay when the SHA-256 of the downloaded zip does not match the digest published in XTLS's .dgst sidecar. This is an integrity gate: TLS protects the transport, not the artifact, so a mismatch means the download is corrupted or tampered with, and the install is aborted so the binary is never run. Expected (from .dgst) and got (computed) digests are both included for comparison.
Source
Thrown at internal/web/service/server.go:941
// sidecar before installing it. TLS protects the transport, not the artifact;
// a corrupted or tampered asset must not be installed and run as xray.
want, err := s.fetchXrayDigestSHA256(client, url+".dgst")
if err != nil {
return "", err
}
if _, err := file.Seek(0, io.SeekStart); err != nil {
return "", err
}
hasher := sha256.New()
if _, err := io.Copy(hasher, file); err != nil {
return "", err
}
if got := hex.EncodeToString(hasher.Sum(nil)); !strings.EqualFold(got, want) {
// User-facing warning: the archive's SHA-256 does not match the official
// release checksum, so the download is corrupted or has been tampered
// with. Abort the install so a bad binary is never run, and tell the user
// to retry/re-download rather than proceed with a mismatched image.
return "", fmt.Errorf("Xray update aborted: the downloaded archive does not match the official SHA-256 checksum, so the image is corrupted or differs from the official release. Please exit and re-download the official image, then try again (expected %s, got %s)", want, got)
}
ok = true
return path, nil
}
// fetchXrayDigestSHA256 downloads the .dgst sidecar XTLS publishes next to each
// release asset and returns the SHA2-256 hex digest it lists.
func (s *ServerService) fetchXrayDigestSHA256(client *http.Client, dgstURL string) (string, error) {
req, reqErr := http.NewRequestWithContext(context.Background(), http.MethodGet, dgstURL, nil)
if reqErr != nil {
return "", fmt.Errorf("download xray checksum: %w", reqErr)
}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("download xray checksum: %w", err)
}
defer resp.Body.Close()View on GitHub (pinned to ad32144c42)
Solutions
- Retry the update — transient corruption is the most common cause
- Compare the two digests shown in the message against the release's official .dgst to distinguish corruption from tampering
- Disable any TLS-intercepting proxy and retry from a clean network path
- If tampering is suspected, download the zip manually from github.com/XTLS/Xray-core/releases and verify with sha256sum before trusting the host
Defensive patterns
Strategy: validation
Validate before calling
// Independent verification before trusting the host
// sha256sum Xray-linux-64.zip → compare with the SHA2-256 line in the release's .dgst
wanted := "<hex from https://github.com/XTLS/Xray-core/releases/download/<ver>/<file>.dgst>"
got := sha256sumFile(zipPath)
if !strings.EqualFold(wanted, got) { /* do not install */ }
Try / catch
err := s.UpdateXray(version)
if err != nil && strings.Contains(err.Error(), "does not match the official SHA-256") {
// never bypass: retry from a clean network, then manual verification; treat persistent mismatch as compromise
return err
}
Prevention
- Never bypass or downgrade a checksum mismatch to a warning
- Retry once for transient corruption; a second mismatch means investigate the network path
- Avoid TLS-intercepting proxies for binary downloads
- Keep expected/got digests in the error so operators can cross-check upstream
When it happens
Trigger: Truncated/corrupted download through a flaky proxy; a compromised or misbehaving mirror/CDN node altering the zip; disk corruption of the temp file; an out-of-sync .dgst fetched for a different asset version than the zip actually served.
Common situations: Updating Xray through an intercepting TLS-terminating proxy; CDN edge inconsistency where zip and .dgst come from different release revisions; packet-level corruption on long transfers.
Related errors
- download xray checksum: unexpected HTTP %d
- xray checksum: malformed SHA2-256 entry in digest
- xray checksum: no SHA2-256 entry in digest
- xray binary exceeds %d bytes
- blocked private/internal address %s
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/4d9292326f169422.
Report an issue: GitHub.