lionsoul2014/ip2region · error

seek to vector index: %w

Error message

seek to vector index: %w

What it means

LoadVectorIndex seeks to offset HeaderInfoLength (right after the header) to read the vector index region. If the Seek call fails, the error is wrapped as 'seek to vector index: %w'. Same root cause family as error 100 but for the vector-index region of the file.

Source

Thrown at binding/golang/xdb/util.go:237

	return header, nil
}

// LoadHeaderFromBuff wrap the header info from the content buffer
func LoadHeaderFromBuff(cBuff []byte) (*Header, error) {
	if len(cBuff) < HeaderInfoLength {
		return nil, fmt.Errorf("invalid content buffer: %d bytes, %d expected", len(cBuff), HeaderInfoLength)
	}

	return NewHeader(cBuff[0:HeaderInfoLength])
}

// LoadVectorIndex util function to load the vector index from the specified file handle
func LoadVectorIndex(handle io.ReadSeeker) ([]byte, error) {
	// load all the vector index block
	_, err := handle.Seek(HeaderInfoLength, 0)
	if err != nil {
		return nil, fmt.Errorf("seek to vector index: %w", err)
	}

	var buff = make([]byte, VectorIndexRows*VectorIndexCols*VectorIndexSize)
	rLen, err := handle.Read(buff)
	if err != nil {
		return nil, err
	}

	if rLen != len(buff) {
		return nil, fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
	}

	return buff, nil
}

// LoadVectorIndexFromFile load vector index from a specified file path
func LoadVectorIndexFromFile(dbFile string) ([]byte, error) {
	handle, err := os.OpenFile(dbFile, os.O_RDONLY, 0600)

View on GitHub (pinned to c1a1fc7d59)

Solutions

  1. Supply a real io.ReadSeeker (*os.File, bytes.Reader) for the xdb file.
  2. Load the entire content once with LoadContentFromFile and use a content-based searcher instead of streaming.
  3. Inspect the wrapped cause with errors.Unwrap to identify the underlying seek failure.

Example fix

// before
vIdx, err := xdb.LoadVectorIndex(pipeReader) // not seekable
// after
cBuff, _ := xdb.LoadContentFromFile("ip2region.xdb")
searcher, err := xdb.NewWithContent(cBuff)
Defensive patterns

Strategy: type-guard

Validate before calling

func isSeekable(r io.Reader) bool {
    _, ok := r.(io.Seeker)
    return ok
}

Type guard

func asReadSeeker(r io.Reader) (io.ReadSeeker, bool) {
    s, ok := r.(io.ReadSeeker)
    return s, ok
}

Try / catch

vIndex, err := xdb.LoadVectorIndex(handle)
if err != nil {
    if strings.Contains(err.Error(), "seek to vector index") {
        return fmt.Errorf("handle is not seekable: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling LoadVectorIndex (or LoadVectorIndexFromFile / Searcher setup) with a non-seekable io.ReadSeeker, or a handle whose seek fails due to a closed/invalid descriptor.

Common situations: Streaming an xdb over HTTP and passing resp.Body directly; using io.SectionReader incorrectly; passing a bytes.Buffer that was wrapped in an unseekable reader.

Related errors


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