lionsoul2014/ip2region · error
incomplete read: readed bytes should be %d
Error message
incomplete read: readed bytes should be %d
What it means
After seeking to 0, LoadHeader reads HeaderInfoLength (256) bytes into a buffer. If the reader returned fewer bytes than the buffer length (rLen != len(buff)), the header is truncated/short and this error is thrown. It guarantees the caller never gets a partially filled Header.
Source
Thrown at binding/golang/xdb/util.go:201
return Verify(handle)
}
// LoadHeader load the header info from the specified handle
func LoadHeader(handle io.ReadSeeker) (*Header, error) {
_, err := handle.Seek(0, 0)
if err != nil {
return nil, fmt.Errorf("seek to the header: %w", err)
}
var buff = make([]byte, HeaderInfoLength)
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 NewHeader(buff)
}
// LoadHeaderFromFile load header info from the specified db file path
func LoadHeaderFromFile(dbFile string) (*Header, error) {
handle, err := os.OpenFile(dbFile, os.O_RDONLY, 0600)
if err != nil {
return nil, fmt.Errorf("open xdb file `%s`: %w", dbFile, err)
}
defer handle.Close()
header, err := LoadHeader(handle)
if err != nil {
return nil, err
}
View on GitHub (pinned to c1a1fc7d59)
Solutions
- Re-download or regenerate the .xdb file — verify it is complete (e.g. compare file size or checksum with the publisher).
- Check file size with os.Stat before calling; it must be at least HeaderInfoLength (256) bytes.
- Use LoadHeaderFromBuff only when you genuinely hold a full header buffer, and never truncate the file first.
Example fix
// before
header, err := xdb.LoadHeader(f) // f points at a truncated file
// after
fi, _ := f.Stat()
if fi.Size() < int64(xdb.HeaderInfoLength) {
return fmt.Errorf("xdb file too small: %d bytes", fi.Size())
}
header, err := xdb.LoadHeader(f) Defensive patterns
Strategy: validation
Validate before calling
fi, err := os.Stat(dbFile)
if err != nil { return err }
if fi.Size() < int64(xdb.HeaderInfoLength) {
return fmt.Errorf("xdb file too small: %d bytes", fi.Size())
} Type guard
func hasCompleteHeader(buf []byte) bool {
return len(buf) >= xdb.HeaderInfoLength
} Try / catch
header, err := xdb.LoadHeader(handle)
if err != nil {
if strings.Contains(err.Error(), "incomplete read") {
return fmt.Errorf("xdb file is truncated; re-download it")
}
return err
} Prevention
- Verify file size/checksum after downloading the xdb
- Run xdb.Verify at startup to detect truncated files early
- Never truncate or partially copy the xdb during deployment
When it happens
Trigger: Calling LoadHeader on a file/reader shorter than 256 bytes, or a reader that returns a short read at EOF — e.g. an empty or truncated .xdb file, or a bytes.Reader constructed from a partial header buffer.
Common situations: Incomplete download of the ip2region.xdb file; a zero-byte file created by a failed generator run; passing a buffer holding only part of the xdb to LoadHeader instead of LoadHeaderFromBuff.
Related errors
- seek to the header: %w
- seek to vector index: %w
- seek to get xdb file length: %w
- incomplete read (${rBytes} read, ${header.HeaderInfoLength}
- invalid input buffer
AI-assisted analysis of lionsoul2014/ip2region@c1a1fc7d59 (2026-09-02).
Data as JSON: /api/errors/0eea47b1cc9be0b5.
Report an issue: GitHub.