{"record":{"id":"f97779f0b77a5b6f","repo":"XTLS/Xray-core","slug":"error-unmarshal-ip-in","errorCode":null,"errorMessage":"error unmarshal IP in ","messagePattern":"error unmarshal IP in ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/geodata/geodat_loader.go","lineNumber":50,"sourceCode":"\t\treturn nil, errors.New(\"failed to open \", file).Base(err)\n\t}\n\tdefer r.Close()\n\tbs, err := find(r, []byte(code), true)\n\tif err != nil {\n\t\treturn nil, errors.New(\"failed to load code \", code, \" from \", file).Base(err)\n\t}\n\treturn bs, nil\n}\n\nfunc loadIP(file, code string) ([]*CIDR, error) {\n\tbs, err := loadFile(file, code)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer runtime.GC() // peak mem\n\tvar geoip GeoIP\n\tif err := proto.Unmarshal(bs, &geoip); err != nil {\n\t\treturn nil, errors.New(\"error unmarshal IP in \", file, \":\", code).Base(err)\n\t}\n\treturn geoip.Cidr, nil\n}\n\nfunc loadSite(file, code string) ([]*Domain, error) {\n\tbs, err := loadFile(file, code)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer runtime.GC() // peak mem\n\tvar geosite GeoSite\n\tif err := proto.Unmarshal(bs, &geosite); err != nil {\n\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) {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/common/geodata/geodat_loader.go#L32-L68","documentation":"Wrapped error from loadIP: the entry bytes for the requested code were found and read, but proto.Unmarshal into the GeoIP message failed — the body is not a valid protobuf-encoded GeoIP payload. The .Base(err) carries the protobuf decode error; the message names the file and code. Effectively 'the dat file entry is corrupted or not in the expected schema'.","triggerScenarios":"loadIP(file, code) where find() matched a byte sequence that is not a well-formed GeoIP entry — corrupted dat, dat from an incompatible fork's schema, or a code collision where the 'header' matched inside unrelated body bytes.","commonSituations":"Corrupted or unofficial geoip.dat builds; dat files converted by third-party tools that mangle entry framing; combining xray with dat files generated for other cores using different schemas.","solutions":["Replace geoip.dat with the official v2fly release and verify its checksum.","If using custom/generated dat files, regenerate them with a tool that emits the standard geodata protobuf format.","Update xray-core in case the dat schema evolved (newer dat + old core)."],"exampleFix":"# before\n$ md5sum geoip.dat # mismatched/corrupt\n9a8b...  geoip.dat\n\n# after\n$ curl -L -o /etc/xray/geoip.dat https://github.com/v2fly/geoip/releases/latest/download/geoip.dat\n$ md5sum /etc/xray/geoip.dat # matches published checksum","handlingStrategy":"validation","validationCode":"// Hash-verify geoip.dat against the published release checksum before starting xray","typeGuard":null,"tryCatchPattern":"cidrs, err := loadIP(file, code)\nif err != nil && strings.Contains(err.Error(), \"error unmarshal IP\") { /* replace dat file */ }","preventionTips":["Use official v2fly geoip.dat only","Checksum-verify after every dat update"],"tags":["geodata","protobuf","corruption","geoip","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}