{"record":{"id":"c24fb5d844e23f56","repo":"XTLS/Xray-core","slug":"varint-overflow","errorCode":null,"errorMessage":"varint overflow","messagePattern":"varint overflow","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/geodata/geodat_loader.go","lineNumber":81,"sourceCode":"\t\treturn nil, errors.New(\"error unmarshal Site in \", file, \":\", code).Base(err)\n\t}\n\treturn geosite.Domain, nil\n}\n\nfunc decodeVarint(br *bufio.Reader) (uint64, error) {\n\tvar x uint64\n\tfor shift := uint(0); shift < 64; shift += 7 {\n\t\tb, err := br.ReadByte()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tx |= (uint64(b) & 0x7F) << shift\n\t\tif (b & 0x80) == 0 {\n\t\t\treturn x, nil\n\t\t}\n\t}\n\t// The number is too large to represent in a 64-bit value.\n\treturn 0, errors.New(\"varint overflow\")\n}\n\nfunc find(r io.Reader, code []byte, readBody bool) ([]byte, error) {\n\tcodeL := len(code)\n\tif codeL == 0 {\n\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)","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/geodata/geodat_loader.go#L63-L99","documentation":"Returned by decodeVarint while scanning the dat file's entry framing: a varint field continued past 64 bits (10+ bytes with the high bit set). Well-formed geodata never has such varints, so this unambiguously signals byte-stream corruption — the scanner has lost alignment or the file is damaged. It surfaces wrapped through the load/check paths.","triggerScenarios":"find() walking a dat file whose bytes are shifted/corrupted (bad download, in-place overwrite during read, wrong file type passed as geodata) so a length field decodes to a >64-bit varint.","commonSituations":"Dat files replaced non-atomically while xray reads them; HTML/text files renamed to .dat; bit rot or truncated-then-appended files.","solutions":["Replace the dat file from the official source and verify its checksum.","Never overwrite dat files in place — write to a temp file and rename so readers see either old or new file.","Ensure the file passed as geodata really is a protobuf dat file, not an error page or archive."],"exampleFix":"# before\n$ cp new_geoip.dat /etc/xray/geoip.dat # in-place overwrite while xray reads\n\n# after\n$ cp new_geoip.dat /etc/xray/geoip.dat.tmp && mv /etc/xray/geoip.dat.tmp /etc/xray/geoip.dat","handlingStrategy":"retry","validationCode":"// Detect non-protobuf files early: a dat file starting with '<' (HTML) or of tiny size is not geodata\nif b, _ := os.ReadFile(p); len(b) > 0 && b[0] == '<' { /* re-provision */ }","typeGuard":null,"tryCatchPattern":"// After any find()/load error chain containing \"varint overflow\", re-download the dat atomically and retry once","preventionTips":["Atomic-replace dat files; never write in place","Keep mirrors out of the dat supply chain"],"tags":["geodata","corruption","parsing","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}