MHSanaei/3x-ui · error

xray checksum: no SHA2-256 entry in digest

Error message

xray checksum: no SHA2-256 entry in digest

What it means

Returned by parseXrayDigestSHA256 when the entire .dgst body contains no line starting with 'SHA2-256=' after trimming. Either the sidecar genuinely lacks the entry (format change to a different algorithm-label style) or the 64 KiB LimitReader truncated the file before the SHA2-256 line — .dgst files normally list hashes in order with SHA2-256 among them, so truncation is the likelier cause.

Source

Thrown at internal/web/service/server.go:984

	}
	return parseXrayDigestSHA256(raw)
}

// parseXrayDigestSHA256 extracts the lowercase SHA2-256 hex from an XTLS .dgst
// file, whose lines are "ALGO= <hex>" (the relevant one being "SHA2-256= ...").
func parseXrayDigestSHA256(dgst []byte) (string, error) {
	for line := range strings.SplitSeq(string(dgst), "\n") {
		rest, ok := strings.CutPrefix(strings.TrimSpace(line), "SHA2-256=")
		if !ok {
			continue
		}
		h := strings.ToLower(strings.TrimSpace(rest))
		if len(h) != 64 {
			return "", fmt.Errorf("xray checksum: malformed SHA2-256 entry in digest")
		}
		return h, nil
	}
	return "", fmt.Errorf("xray checksum: no SHA2-256 entry in digest")
}

func (s *ServerService) UpdateXray(version string) error {
	versions, err := s.GetXrayVersions()
	if err != nil {
		return err
	}
	if !slices.Contains(versions, version) {
		return fmt.Errorf("xray version %q is not in the fetched release list", version)
	}

	// 1. Stop xray before doing anything
	if err := s.StopXrayService(); err != nil {
		logger.Warning("failed to stop xray before update:", err)
	}

	// 2. Download the zip
	zipFileName, err := s.downloadXRay(version)

View on GitHub (pinned to ad32144c42)

Solutions

  1. Fetch the .dgst manually and grep for the SHA2-256 line to see the real layout/size
  2. If the file simply changed label style, update parseXrayDigestSHA256 to match and rebuild
  3. If truncated (>64 KiB), raise maxXrayDigestBytes in internal/web/service/server.go
Defensive patterns

Strategy: validation

Validate before calling

dgst := fetchAll(dgstURL)
if !bytes.Contains(dgst, []byte("SHA2-256=")) {
    return errors.New("sidecar lacks SHA2-256; possibly truncated or reformatted")
}

Prevention

When it happens

Trigger: A .dgst larger than 64 KiB (many algorithms/files listed) where SHA2-256 appears past the cutoff; upstream renaming the label (e.g. 'sha256='); an HTML error body served with 200 from a proxy.

Common situations: Format drift in XTLS release tooling; proxies returning fake-200 HTML; oversized multi-file digest sidecars.

Related errors


AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15). Data as JSON: /api/errors/26b56ab68dc9ff10. Report an issue: GitHub.