{"record":{"id":"b0e579ebc7256d95","repo":"XTLS/Xray-core","slug":"invalid-body-length","errorCode":null,"errorMessage":"invalid body length: ","messagePattern":"invalid body length: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/geodata/geodat_loader.go","lineNumber":105,"sourceCode":"\t\treturn nil, errors.New(\"empty code\")\n\t}\n\n\tbr := bufio.NewReaderSize(r, 64*1024)\n\tneed := 2 + codeL // TODO: if code too long\n\tprefixBuf := make([]byte, need)\n\n\tfor {\n\t\tif _, err := br.ReadByte(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tx, err := decodeVarint(br)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbodyL := int(x)\n\t\tif bodyL <= 0 {\n\t\t\treturn nil, errors.New(\"invalid body length: \", bodyL)\n\t\t}\n\n\t\tprefixL := bodyL\n\t\tif prefixL > need {\n\t\t\tprefixL = need\n\t\t}\n\t\tprefix := prefixBuf[:prefixL]\n\t\tif _, err := io.ReadFull(br, prefix); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tmatch := false\n\t\tif bodyL >= need {\n\t\t\tif int(prefix[1]) == codeL && bytes.Equal(prefix[2:need], code) {\n\t\t\t\tif !readBody {\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t\tmatch = true","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/geodata/geodat_loader.go#L87-L123","documentation":"Returned by find() when an entry's body length, decoded from its varint, converts to a non-positive int (bodyL <= 0). A zero length means the entry header matched but declares an empty body (invalid for GeoIP/GeoSite entries); a negative value means the varint exceeded maxint64 (e.g. 2^63), which cannot be a real body size. Both indicate a corrupted or misaligned dat stream.","triggerScenarios":"Scanning a dat file whose framing bytes are corrupt so that a length varint decodes to 0 or to a huge value that overflows int — bad downloads, files damaged mid-transfer, or a non-geodata file fed to the loader.","commonSituations":"Truncated dat downloads where scanning continues past valid data; dat files corrupted by sync tools; code strings that accidentally match inside body bytes of a misaligned stream (long/short code handling is bounded by 'need').","solutions":["Re-download the dat file from official releases and verify size/checksum before deploying.","Deploy dat updates atomically (temp file + rename) so readers never see partially written files.","Keep the xray asset directory free of unrelated files and confirm filenames."],"exampleFix":"# before\n$ sha256sum /etc/xray/geosite.dat # differs from published hash\n\n# after\n$ curl -sL -o /tmp/dlc.dat https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat\n$ sha256sum /tmp/dlc.dat # verify against release notes, then:\n$ mv /tmp/dlc.dat /etc/xray/geosite.dat","handlingStrategy":"retry","validationCode":"// Pre-verify integrity via checksum; also sanity-check file size against the published release size","typeGuard":null,"tryCatchPattern":"// On \"invalid body length\", treat the dat as corrupt: re-download to temp, verify hash, rename, retry load","preventionTips":["Checksum dat files after download","Deploy updates atomically to avoid torn reads"],"tags":["geodata","corruption","parsing","download","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}