lionsoul2014/ip2region · error

read region at %d: %w

Error message

read region at %d: %w

What it means

Go xdb searcher: after locating the matching segment, reading the region data at dataPtr failed in read(); the wrapped cause (seek/read error or short read) points to file truncation or corruption at the data offset.

Source

Thrown at binding/golang/xdb/searcher.go:198

		} else if s.version.IPCompare(ipBytes, buff[bytes:dBytes]) > 0 {
			l = m + 1
		} else {
			dataLen = int(binary.LittleEndian.Uint16(buff[dBytes:]))
			dataPtr = binary.LittleEndian.Uint32(buff[dBytes+2:])
			break
		}
	}

	// fmt.Printf("dataLen: %d, dataPtr: %d\n", dataLen, dataPtr)
	if dataLen == 0 {
		return "", nil
	}

	// load and return the region data
	var regionBuff = make([]byte, dataLen)
	err = s.read(int64(dataPtr), regionBuff)
	if err != nil {
		return "", fmt.Errorf("read region at %d: %w", dataPtr, err)
	}

	return string(regionBuff), nil
}

// do the data read operation based on the setting.
// content buffer first or will read from the file.
// this operation will invoke the Seek for file based read.
func (s *Searcher) read(offset int64, buff []byte) error {
	if s.contentBuff != nil {
		cLen := copy(buff, s.contentBuff[offset:])
		if cLen != len(buff) {
			return fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
		}
	} else {
		_, err := s.dbReader.Seek(offset, 0)
		if err != nil {
			return fmt.Errorf("seek to %d: %w", offset, err)

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Re-download or regenerate the xdb file — the data section is truncated or corrupt.
  2. Ensure header, content buffer, and file all come from the SAME xdb build/version.
  3. For file searchers, verify the file wasn't replaced while open; reopen the searcher.
  4. Check the wrapped OS error for permission/EOF causes.

Example fix

// before
header, _ := xdb.LoadHeaderFromFile(oldPath)
searcher, _ := xdb.LoadContentFromFile(newPath) // mismatched sources
// after
header, _ := xdb.LoadHeaderFromFile(path)
content, _ := xdb.LoadContentFromFile(path) // same path/build
Defensive patterns

Strategy: validation

Validate before calling

fi, _ := os.Stat(xdbPath)
hdr, _ := xdb.LoadHeaderFromFile(xdbPath)
if fi.Size() != int64(hdr.Length) {
    return fmt.Errorf("xdb incomplete: on-disk %d, header says %d", fi.Size(), hdr.Length)
}

Try / catch

region, err := searcher.Search(ctx, ip)
if err != nil {
    if strings.Contains(err.Error(), "read region") {
        return "", fmt.Errorf("region data unreadable — xdb likely truncated: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: File read/seek failure at dataPtr; xdb truncated so the data section is missing; corrupted index block yielding an out-of-range dataPtr (e.g., mixing buffers from two different xdb files).

Common situations: Partially downloaded xdb (index intact, data tail missing); pairing a header/content buffer from one xdb version with a searcher/file of another; storage errors on network mounts.

Related errors


AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02). Data as JSON: /api/errors/d52ec915e49e5bb1. Report an issue: GitHub.