lionsoul2014/ip2region · error
incomplete read: readed bytes should be %d
Error message
incomplete read: readed bytes should be %d
What it means
read() copies from the in-memory content buffer when available; if copy() moved fewer bytes than the requested buffer length, the offset range extends past the content buffer and this error is returned naming the expected byte count.
Source
Thrown at binding/golang/xdb/searcher.go:211
// 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)
}
s.ioCount++
rLen, err := s.dbReader.Read(buff)
if err != nil {
return fmt.Errorf("handle read: %w", err)
}
if rLen != len(buff) {
return fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
}
}
View on GitHub (pinned to c1a1fc7d59)
Solutions
- Verify len(contentBuff) equals the full xdb file size before creating the searcher.
- Re-download/regenerate the xdb; it is truncated.
- Ensure header and content buffer are from the same file build.
- Validate offsets: header.Length should be <= len(contentBuff).
Example fix
// before
buff, _ := os.ReadFile(path)
searcher, _ := xdb.NewSearcher(header, buff) // buff truncated upstream
// after
buff, err := os.ReadFile(path)
if err != nil { return err }
if len(buff) < header.Length {
return fmt.Errorf("xdb content too small: %d < %d", len(buff), header.Length)
}
searcher, err := xdb.NewSearcher(header, buff) Defensive patterns
Strategy: validation
Validate before calling
if len(contentBuff) < header.Length {
return fmt.Errorf("content buffer %d bytes < header length %d", len(contentBuff), header.Length)
} Type guard
func sufficientContent(h *xdb.Header, buff []byte) bool { return len(buff) >= h.Length } Try / catch
region, err := searcher.Search(ctx, ip)
if err != nil && strings.Contains(err.Error(), "incomplete read") {
return "", fmt.Errorf("xdb content buffer truncated — reload full file: %w", err)
} Prevention
- Always pass the complete file bytes to content-buffer searchers.
- Check len(buff) against header.Length at load time.
- Avoid copying content buffers with slicing that could drop the tail.
- Regenerate/re-download the xdb if sizes disagree.
When it happens
Trigger: Any Search/read at an offset beyond len(contentBuff): content buffer smaller than the real xdb (truncated file passed to LoadContentFromBuff), or a corrupted index pointing past the buffer end.
Common situations: Truncated download; loading a v4 header with a v6 content buffer (or vice versa); reading an xdb whose contentBuff was sliced/trimmed by the caller.
Related errors
- invalid input buffer
- read vector index block at %d: %w
- read segment index at %d: %w
- read region at %d: %w
- seek to the header: %w
AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02).
Data as JSON: /api/errors/c9845daf3e7c7d06.
Report an issue: GitHub.