XTLS/Xray-core · error
error unmarshal IP in
Error message
error unmarshal IP in
What it means
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'.
Source
Thrown at common/geodata/geodat_loader.go:50
return nil, errors.New("failed to open ", file).Base(err)
}
defer r.Close()
bs, err := find(r, []byte(code), true)
if err != nil {
return nil, errors.New("failed to load code ", code, " from ", file).Base(err)
}
return bs, nil
}
func loadIP(file, code string) ([]*CIDR, error) {
bs, err := loadFile(file, code)
if err != nil {
return nil, err
}
defer runtime.GC() // peak mem
var geoip GeoIP
if err := proto.Unmarshal(bs, &geoip); err != nil {
return nil, errors.New("error unmarshal IP in ", file, ":", code).Base(err)
}
return geoip.Cidr, nil
}
func loadSite(file, code string) ([]*Domain, error) {
bs, err := loadFile(file, code)
if err != nil {
return nil, err
}
defer runtime.GC() // peak mem
var geosite GeoSite
if err := proto.Unmarshal(bs, &geosite); err != nil {
return nil, errors.New("error unmarshal Site in ", file, ":", code).Base(err)
}
return geosite.Domain, nil
}
func decodeVarint(br *bufio.Reader) (uint64, error) {View on GitHub (pinned to 7d214f8b09)
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).
Example fix
# before $ md5sum geoip.dat # mismatched/corrupt 9a8b... geoip.dat # after $ curl -L -o /etc/xray/geoip.dat https://github.com/v2fly/geoip/releases/latest/download/geoip.dat $ md5sum /etc/xray/geoip.dat # matches published checksum
Defensive patterns
Strategy: validation
Validate before calling
// Hash-verify geoip.dat against the published release checksum before starting xray
Try / catch
cidrs, err := loadIP(file, code)
if err != nil && strings.Contains(err.Error(), "error unmarshal IP") { /* replace dat file */ } Prevention
- Use official v2fly geoip.dat only
- Checksum-verify after every dat update
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- error unmarshal Site in
- unknown domain type:
- failed to load code
- varint overflow
- invalid body length:
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/f97779f0b77a5b6f.
Report an issue: GitHub.