{"record":{"id":"26b56ab68dc9ff10","repo":"MHSanaei/3x-ui","slug":"xray-checksum-no-sha2-256-entry-in-digest","errorCode":null,"errorMessage":"xray checksum: no SHA2-256 entry in digest","messagePattern":"xray checksum: no SHA2-256 entry in digest","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/web/service/server.go","lineNumber":984,"sourceCode":"\t}\n\treturn parseXrayDigestSHA256(raw)\n}\n\n// parseXrayDigestSHA256 extracts the lowercase SHA2-256 hex from an XTLS .dgst\n// file, whose lines are \"ALGO= <hex>\" (the relevant one being \"SHA2-256= ...\").\nfunc parseXrayDigestSHA256(dgst []byte) (string, error) {\n\tfor line := range strings.SplitSeq(string(dgst), \"\\n\") {\n\t\trest, ok := strings.CutPrefix(strings.TrimSpace(line), \"SHA2-256=\")\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\th := strings.ToLower(strings.TrimSpace(rest))\n\t\tif len(h) != 64 {\n\t\t\treturn \"\", fmt.Errorf(\"xray checksum: malformed SHA2-256 entry in digest\")\n\t\t}\n\t\treturn h, nil\n\t}\n\treturn \"\", fmt.Errorf(\"xray checksum: no SHA2-256 entry in digest\")\n}\n\nfunc (s *ServerService) UpdateXray(version string) error {\n\tversions, err := s.GetXrayVersions()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !slices.Contains(versions, version) {\n\t\treturn fmt.Errorf(\"xray version %q is not in the fetched release list\", version)\n\t}\n\n\t// 1. Stop xray before doing anything\n\tif err := s.StopXrayService(); err != nil {\n\t\tlogger.Warning(\"failed to stop xray before update:\", err)\n\t}\n\n\t// 2. Download the zip\n\tzipFileName, err := s.downloadXRay(version)","sourceCodeStart":966,"sourceCodeEnd":1002,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/service/server.go#L966-L1002","documentation":"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.","triggerScenarios":"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.","commonSituations":"Format drift in XTLS release tooling; proxies returning fake-200 HTML; oversized multi-file digest sidecars.","solutions":["Fetch the .dgst manually and grep for the SHA2-256 line to see the real layout/size","If the file simply changed label style, update parseXrayDigestSHA256 to match and rebuild","If truncated (>64 KiB), raise maxXrayDigestBytes in internal/web/service/server.go"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"dgst := fetchAll(dgstURL)\nif !bytes.Contains(dgst, []byte(\"SHA2-256=\")) {\n    return errors.New(\"sidecar lacks SHA2-256; possibly truncated or reformatted\")\n}\n","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Size digest-sidecar reads generously above the real file size to avoid truncation","Fail closed when the integrity source cannot be parsed — never install unverified","Watch upstream artifact-format announcements if you parse their metadata"],"tags":["xray-update","checksum","parsing"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}