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

  1. Replace geoip.dat with the official v2fly release and verify its checksum.
  2. If using custom/generated dat files, regenerate them with a tool that emits the standard geodata protobuf format.
  3. 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

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


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/f97779f0b77a5b6f. Report an issue: GitHub.